初級算法合集
缺失的數字
class Solution { public: int missingNumber(vector<int>& nums) { int n = nums.size(); int sum = n*(n+1)/2; for(int i=0;i<nums.size();i++) { sum-=nums[i]; } return sum; } };
旋轉數組
class Solution { public: void rotate(vector<int>& nums, int k) { k %= nums.size(); k = nums.size()-k; if(nums.size()<2)return; reverse(&nums[0],&nums[k]); reverse(&nums[k],&nums[nums.size()]); reverse(nums.begin(),nums.end()); } };
【leetcode】【股票們】
買賣股票的最佳時機1
只能完成一筆交易
第i天的利潤 = max(不賣,賣)
動態規劃
class Solution { public: int maxProfit(vector<int>& prices) { int n = prices.size(); if(n==0)return 0; // dp[i] = max(dp[i-1],prices[i]-min(prices[0~i-1])); int dp[n]; int m[n]; for(int i=0;i<n;i++) { if(i==0) { m[i] = prices[i]; } else { m[i] = min(prices[i],m[i-1]); } } dp[0] = 0; for(int i=1;i<n;i++) { dp[i] = max(dp[i-1],prices[i]-m[i-1]); } return dp[n-1]; } };
模板寫法,分爲買入、賣出、休息三個狀態
class Solution { public: int maxProfit(vector<int>& prices) { int n = prices.size(); if(n==0)return 0; int dp[n][2]; dp[0][0] = 0; dp[0][1] = -prices[0]; for(int i=1;i<n;i++) { dp[i][0] = max(dp[i-1][0],dp[i-1][1]+prices[i]); dp[i][1] = max(dp[i-1][1],-prices[i]); } return dp[n-1][0]; } };
買賣股票的最佳時機2
就很簡單,只要找到遞增的和就可以,沒用到什麼算法
class Solution { public: int maxProfit(vector<int>& prices) { int n = prices.size(); int sum = 0; for(int i=1;i<n;i++) { if(prices[i]-prices[i-1]>0) { sum += prices[i]-prices[i-1]; } } return sum; } };
買賣股票的最佳時機3
交易兩次
動態規劃
//dp枚舉 //每天有三種狀態:賣出、買入、無操作 //K爲最大交易次數 dp[n][K][2]; for 0<=i<n for 1<=k<=K if s in(0,1) dp[i][k][s] = max(buy, sell, rest)
使用模板
class Solution { public: int maxProfit(vector<int>& prices) { int n = prices.size(); if(!n)return 0; int dp[n][3][2]; dp[0][0][0] = 0; dp[0][1][0] = 0; dp[0][1][1] = -prices[0]; dp[0][2][0] = 0; dp[0][2][1] = -prices[0]; for(int i=1;i<n;i++) { //交易過一次現在不持有 = max(rest,sell——賣掉當天的) dp[i][1][0] = max(dp[i-1][1][0],dp[i-1][1][1]+prices[i]); //交易過2次現在不持有 = max(rest,sell——賣掉當天的) dp[i][2][0] = max(dp[i-1][2][0],dp[i-1][2][1]+prices[i]); //交易過一次現在持有 = max(rest,buy) dp[i][1][1] = max(dp[i-1][1][1],-prices[i]); //交易過2次現在持有 = max(rest,buy) dp[i][2][1] = max(dp[i-1][2][1],dp[i-1][1][0]-prices[i]); } return dp[n-1][2][0]; } };
買賣股票的最佳時機4
class Solution { public: int maxProfit(int k, vector<int>& prices) { int n = prices.size(); if(!n)return 0; if(k>(n/2)) { int sum = 0; for(int i=1;i<n;i++) { if(prices[i]-prices[i-1]>0) sum+=(prices[i]-prices[i-1]); } return sum; } int dp[n][k+1][2]; memset(dp,0,sizeof(dp)); for(int i=0;i<n;i++) { for(int kk=1;kk<=k;kk++) { if(i==0) { dp[0][kk][1] = -prices[i]; dp[0][kk][0] = 0; dp[0][0][0] = 0; } else { dp[i][kk][1] = max(dp[i-1][kk][1],dp[i-1][kk-1][0]-prices[i]); dp[i][kk][0] = max(dp[i-1][kk][0],dp[i-1][kk][1]+prices[i]); } } } return dp[n-1][k][0]; } };
咳咳。。好的,又回來繼續做初級算法
存在重複數字
class Solution { public: bool containsDuplicate(vector<int>& nums) { map<int,int> mm; int n = nums.size(); for(int i=0;i<n;i++) { if(mm.find(nums[i])==mm.end()) mm[nums[i]] = 1; else return true; } return false; } };
只出現一次的數字
異或
class Solution { public: int singleNumber(vector<int>& nums) { int n = nums.size(); int ans = 0; for(int i=0;i<n;i++) { ans^=nums[i]; } return ans; } };
兩個數組的交集
class Solution { public: vector<int> intersect(vector<int>& nums1, vector<int>& nums2) { vector<int> ans; map<int,int> mm; int n1 = nums1.size(); for(int i=0;i<n1;i++) { if(mm.find(nums1[i])==mm.end()) { mm[nums1[i]] = 1; } else mm[nums1[i]]++; } int n2 = nums2.size(); for(int i=0;i<n2;i++) { if(mm.find(nums2[i])!=mm.end()&&mm[nums2[i]]!=0) { mm[nums2[i]]--; ans.push_back(nums2[i]); } } return ans; } };
加1
class Solution { public: vector<int> plusOne(vector<int>& digits) { vector<int> ans; int i; int jin = 0; int n = digits.size(); for(i = n-1;i>=0;i--) { if(i == n-1) { jin = ((digits[i])+1)/10; ans.push_back(((digits[i])+1)%10); } else { ans.push_back(((digits[i])+jin)%10); jin = ((digits[i])+jin)/10; } printf("%d %d\n",jin,digits[i]); } if(jin)ans.push_back(jin); reverse(ans.begin(),ans.end()); return ans; } };
爬樓梯(重做)
class Solution { public: int climbStairs(int n) { int dp[n+1]; memset(dp,0,sizeof(dp)); dp[1] = 1; if(n==1)return 1; dp[2] = 2; for(int i=3;i<=n;i++) { dp[i] = dp[i-1]+dp[i-2]; } return dp[n]; } };
最大連續和(重做)
class Solution { public: int maxSubArray(vector<int>& nums) { int sum = -1; int ans = INT_MIN; int n = nums.size(); for(int i=0;i<n;i++) { if(sum<=0) { sum = nums[i]; } else sum+=nums[i]; ans = max(ans,sum); } return ans; } };
二叉樹的最大深度
/** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */ class Solution { public: int depth(TreeNode* root) { if(root==NULL)return 0; return(max(depth(root->left)+1,depth(root->right)+1)); } int maxDepth(TreeNode* root) { return depth(root); } };