爲提高算法、編程能力,開始刷LeetCode,一些於我有益的題記錄在此係列中(或許對大佬們而言滿是些簡單的題,還請見諒)。同時感謝解體區的大佬們。
Pure mathematics is, in this way, the poetry of logical ideas. -- Einstein
給定一個整數數組,每次move
操做能夠數組中任意元素,將其增1。問move
操做數最少能夠爲多少,使數組中每一個數都是惟一的,參LeetCode 945. 使數組惟一的最小增量。算法
先排序,後遍歷:時間複雜度$O(n\log n)$編程
public int minIncrementForUnique(vector<int>& A) { //先排序 sort(A.begin(), A.end()); int count = 0; //再遍歷,若當前元素小於等於前一個,則變爲前一個元素加1 for(int i=1; i<A.size(); i++){ if(A[i]<=A[i-1]){ count += A[i-1]+1-A[i]; A[i] = A[i-1]+1; } } return count; }
計數排序,用空間換時間:時間複雜度$O(n)$數組
public int minIncrementForUnique(vector<int>& A) { int counter[50000] = {0}; //計數 for(int i=0; i<A.size(); i++){ counter[A[i]]++; } int count = 0; //若是同一個數的數量n大於1,則將n-1個數移入下一個位置 for(int i=0; i<50000; i++){ if(counter[i]>1){ count+=counter[i]-1; counter[i+1]+=counter[i]-1; } } return count; }
已知一個非空單鏈表的頭指針head
,要求返回鏈表的中間節點(如有兩個中間節點,則返回第二個中間節點),參LeetCode 876. 鏈表的中間結點ide
遍歷鏈表獲得長度,找到中間長度,再遍歷獲得。this
ListNode* middleNode(ListNode* head) { int count = 0; int runNum = 0; ListNode *p = head; while (p->next != NULL) { p = p->next; ++count; } runNum = (count + 1) / 2 + 1; p = head; for (count = 1; count < runNum; ++count) { p = p->next; } return p; }
使用快慢指針,快指針一次走兩步,慢指針一次走一步。編碼
public ListNode* middleNode(ListNode* head) { ListNode* fast = head; ListNode* slow = head; while (fast != NULL && fast->next!=NULL) { fast = (fast->next)->next; slow = slow->next; } return slow; }
給定一個非負整數數組,按序找出一個相鄰兩數在原數組中不相鄰的子序列,求最大和,參LeetCode 198. 打家劫舍。idea
編碼實現以下:指針
public int rob(vector<int>& nums) { vector<int> dp(nums.size(),0); if(nums.size()==0) return 0; else if(nums.size()==1) return nums[0]; dp[0] = nums[0]; dp[1] = max(nums[0],nums[1]); for(int i=2; i<nums.size(); i++){ dp[i] = max(dp[i-1],dp[i-2]+nums[i]); } return dp[nums.size()-1]; }
繼續,繼續~