算法 day6
【leetcode】环形链表2
/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */ class Solution { public: ListNode *detectCycle(ListNode *head) { ListNode* fast = head; ListNode* slow = head; while(fast!=NULL && slow!=NULL) { fast = fast->next; slow = slow->next; if(fast!=NULL)fast = fast->next; else return NULL; if(fast == slow) break; } if(fast!=NULL&&slow!=NULL&&fast == slow) { fast = head; while(fast!=slow) { fast = fast->next; slow = slow->next; } return fast; } else return NULL; } };
继续复习数组、字符串。
实现strstr()
使用KMP算法 时间复杂度O(m+n)
class Solution { public: void getnext(int* next,string p) { int j = -1; next[0] = j; for(int i=1;i<p.length();i++) { while(j>=0 && p[j+1]!=p[i]) { j = next[j]; } if(p[j+1]==p[i]) j++; next[i] = j; } } int strStr(string s, string p) { if(s.length() == 0) { if(p.length()!=0) return -1; else return 0; } if(p.length()==0)return 0; int next[p.length()]; getnext(next,p); int j=-1; for(int i=0;i<s.length();i++) { while(j>=0 && s[i]!=p[j+1]) { j = next[j]; } if(s[i] == p[j+1]) { j++; } if(j == p.length()-1) { return i-p.length()+1; } } return -1; } };
数组拆分
class Solution { public: int arrayPairSum(vector<int>& nums) { sort(nums.begin(),nums.end()); int n = nums.size()/2; int sum = 0; for(int i=0;i<n;i++) { sum+=nums[i*2]; } return sum; } };
两数之和
class Solution { public: vector<int> twoSum(vector<int>& numbers, int target) { int left = 0; int right = numbers.size()-1; int sum = 0; vector<int> ans; while(left<right) { sum = numbers[left]+numbers[right]; if(sum>target) { right--; } else if(sum<target) { left++; } else { ans.push_back(left+1); ans.push_back(right+1); return ans; } } return ans; } };
移除指定元素o(n)
class Solution { public: int removeElement(vector<int>& nums, int val) { int ccount = 0; for(int i=0;i<nums.size();i++) { if(nums[i]!=val) { nums[ccount++] = nums[i]; } } return ccount; } };
连续最大的1
class Solution { public: int findMaxConsecutiveOnes(vector<int>& nums) { int ccount = 0; int max = -1; for(int i=0;i<nums.size();i++) { if(nums[i] == 1) ccount++; if(nums[i] == 0 || i == nums.size()-1) { if(ccount>max)max = ccount; ccount = 0; } } return max; } };
连续长度最小数组
class Solution { public: int minSubArrayLen(int s, vector<int>& nums) { int n = nums.size(); if(n==0)return 0; int left = 0; int right = 1; int sum = nums[0]; int len = INT_MAX; //[a,b) 左闭右开 while(left<n&&right<n+1) { if(sum<s) { if(right<n) sum+=nums[right]; right++; } else if(sum>=s) { len = min(len,right-left); sum-=nums[left]; left++; } printf("%d %d %d\n",left,right,sum); } if(len == INT_MAX)return 0; return len; } };
杨辉三角
class Solution { public: vector<vector<int>> generate(int numRows) { vector<vector<int>> ans; vector<int> row; if(numRows == 0) return ans; row.push_back(1); ans.push_back(row); for(int i=1;i<numRows;i++) { vector<int> row; for(int j=0;j<i+1;j++) { if(j == 0)row.push_back(1); else if(j == i)row.push_back(1); else { row.push_back(ans[i-1][j-1]+ans[i-1][j]); } } ans.push_back(row); } return ans; } };
杨辉三角2
注意组合数的算法c(n,k+1) = (n-k)/k+1 * c(n,k)
class Solution { public: vector<int> getRow(int rowIndex) { vector<int> ans; ans.push_back(1); if(rowIndex == 0)return ans; long long pre = 1; for(int i=1;i<rowIndex;i++) { long long tmp = pre*(rowIndex-i+1)/i; ans.push_back(tmp); pre = tmp; } ans.push_back(1); return ans; } };
翻转字母
class Solution { public: string reverseWords(string s) { int left = 0; int word = 0; for(int i=0;i<s.length();i++) { if(s[i]!=' ') { if(word == 0 ) { printf("%d\n",i); left = i; word = 1; } } if(i == s.length()-1||s[i+1] == ' ' ) { if(word == 1) { reverse(&s[left],&s[i+1]); word = 0; } } } return s; } };
旋转数组找最小
class Solution { public: int findMin(vector<int>& a) { for(int i=0;i<a.size()-1;i++) { if(a[i]>a[i+1]) { return a[i+1]; } } return a[0]; } };
其实是一个二分问题,要使用二分法
class Solution { public: int findMin(vector<int>& nums) { int left = 0; int right = nums.size()-1; while(left<right) { int mid = (right-left)/2 + left; if(nums[mid]<=nums[right]) { right = mid; } else if(nums[mid]>nums[right]) { left = mid+1; } } return nums[left]; } };
删除重复的元素
class Solution { public: int removeDuplicates(vector<int>& nums) { int ccount = 0; int pre; for(int i=0;i<nums.size();i++) { if(i==0||pre!=nums[i]) { nums[ccount++] = nums[i]; pre = nums[i]; } } return ccount; } };
把所有的0移动到数列的最末端,时间复杂度o(n)
class Solution { public: void moveZeroes(vector<int>& nums) { int ccount = 0; int left,right; left = right = 0; while(right<nums.size()) { if(nums[right]==0) { right++; ccount++; } else { nums[left] = nums[right]; right++; left++; } } while(ccount--) { nums[left++] = 0; } } };
数组字符串练习完结~~撒花*★,°*:.☆( ̄▽ ̄)/$:*.°★* 。