32. Longest valid bracket
Code: dynamic planning
class Solution { public: int longestValidParentheses(string s) { int len = s.size(); if(len == 0)return 0; int dp[len]; for(int i = 0;i<len;i++)dp[i]=0;//Initialize array for(int i=1;i<len;i++){ if(s[i] == ')'){//Right bracket encountered trying to match left bracket forward int pre = i - dp[i-1] -1 ; if(pre>=0&&s[pre] == '('){//Update match length if match to left bracket dp[i] = dp[i-1] +2; if (pre>0){ dp[i]+=dp[pre-1]; } } } } return *max_element(dp,dp+len); } };
33. Search rotation sort array
Code: skillfully analyze the problem and use exclusive or method to solve it
class Solution { public: int search(vector<int>& nums, int target) { int left=0,right= nums.size()-1; int mid; while(left<right){ mid = (left+right)/2; if((nums[0]>target)^(nums[0]>nums[mid])^(target>nums[mid])){ left = mid +1; } else right = mid; } return left == right && nums[left] == target ? left : -1; } };
34. Find the first and last positions of elements in the sorting array
Refer to the detailed dichotomy tutorial: https://leetcode-cn.com/problems/find-first-and-last-position-of-element-in-sorted-array/solution/er-fen-cha-zhao-fa-xi-jie-jie-by-laboratory/
Code:
class Solution { public: vector<int> searchRange(vector<int>& nums, int target) { vector<int>ans; ans.push_back(left(nums,target)); ans.push_back(right(nums,target)); return ans; } int left(vector<int>&nums,int target){//Left boundary if(nums.size()==0)return -1; int i=0,j=nums.size(),mid=0; while(i<j){ mid = i+(j-i)/2;//Prevent overflow if(nums[mid]==target)j=mid;//Shrink left boundary else if(nums[mid]>target)j=mid; else if(nums[mid]<target)i=mid + 1; } if(i==nums.size())return -1; else return nums[i]==target?i:-1; } int right(vector<int>&nums,int target){//Right border if(nums.size()==0)return -1; int i=0,j=nums.size(),mid=0; while(i<j){ mid = i+(j-i)/2; if(nums[mid]==target)i=mid+1;//Shrink right boundary else if(nums[mid]>target)j=mid; else if(nums[mid]<target)i=mid+1; } if(j==0)return -1; else return nums[j-1]==target?j-1:-1; } };
35. Search insertion location
Code: use dichotomy directly
class Solution { public: int searchInsert(vector<int>& nums, int target) { int i=0,j=nums.size()-1; int mid; while(i<=j){ mid = i+(j-i)/2; if(nums[mid]==target)return mid; else if(nums[mid]>target)j=mid-1; else if(nums[mid]<target)i=mid+1; } return i; } };
36. Effective Sudoku
Code 1: violent solution
class Solution { public: bool isValidSudoku(vector<vector<char>>& board) { int row[9][9]={0}; int col[9][9]={0}; int block[9][9]={0}; for(int i =0;i<9;i++){ for(int j=0;j<9;j++){ if(board[i][j]!='.'){ int num = board[i][j] -'1'; int blockindex = i/3*3+j/3; if(row[i][num] || col[j][num] || block[blockindex][num])return false; else{ row[i][num] = true; col[j][num] = true; block[blockindex][num] = true; } } } } return true; } };
37. solution independence
Code: the main idea is to use recursion method for backtracking
class Solution { public: void solveSudoku(vector<vector<char>>& board) { bool rowUsed[9][10] ={false},colUsed[9][10]={false},boxUsed[3][3][10]={false}; for(int row=0;row<9;row++){ for(int col=0;col<9;col++){ int num = board[row][col] - '0'; if((num>0)&&(num<10)){ rowUsed[row][num] = true; colUsed[col][num] = true; boxUsed[row/3][col/3][num] =true; } } } solve_digui(board,rowUsed,colUsed,boxUsed,0,0); } bool solve_digui(vector<vector<char>>& board,bool rowUsed[][10] ,bool colUsed[][10] ,bool boxUsed[][3][10],int row,int col){ if(col == 9){ col = 0; row++; if(row == 9)return true; } if(board[row][col]=='.'){ for(int num=1;num<=9;num++){ bool canused = !(rowUsed[row][num]||colUsed[col][num]||boxUsed[row/3][col/3][num]); if(canused){ rowUsed[row][num] = true; colUsed[col][num] = true; boxUsed[row/3][col/3][num] = true; board[row][col] = '0'+num; if(solve_digui(board,rowUsed,colUsed,boxUsed,row,col+1)){ return true; } board[row][col] = '.'; rowUsed[row][num] = false; colUsed[col][num] = false; boxUsed[row/3][col/3][num] = false; } } } else{ return solve_digui(board,rowUsed,colUsed,boxUsed,row,col+1); } return false; } };
38. Appearance series
Code:
class Solution { public: string countAndSay(int n) { int i =1; string s = to_string(1); while(i<n){ s = count1(s); i++; } return s; } string count1(string s){ string r; int i = 0; while(i<s.size()){ int times = 1; while(s[i] == s[i+1]){ times+=1; i++; } r += to_string(times); r +=s[i]; i++; } return r; } };
39. Sum of combinations
Code: using backtracking algorithm and pruning
Reference: https://leetcode-cn.com/problems/combination-su m/solution/hui-su-suan-fa-jian-zh-python-dai-ma-java-dai-m-2/
class Solution { public: vector<vector<int>> res; vector<int> path; vector<vector<int>> combinationSum(vector<int>& candidates, int target) { res.clear(); path.clear(); todo(candidates,target); return res; } void todo(vector<int>& candidates,int target){ for(int i=0;i<candidates.size();i++){ if((candidates[i]>target)||(path.size()&&candidates[i]<path[path.size()-1])) continue; path.push_back(candidates[i]); if(candidates[i]==target)res.push_back(path); else todo(candidates,target-candidates[i]); path.pop_back(); } } };
40. Combined summation2
Similar to the previous question, the next traversal starts from i+1
class Solution { public: vector<int>path; vector<vector<int>> res; vector<int>candidates; vector<vector<int>> combinationSum2(vector<int>& candidates, int target) { sort(candidates.begin(),candidates.end()); this->candidates = candidates; todo(0,target); return res; } void todo(int start,int target){ if(target == 0){ res.push_back(path); return; } for(int i = start;i<candidates.size()&&target-candidates[i]>=0;i++){ if (i > start && candidates[i] == candidates[i - 1]) continue; path.push_back(candidates[i]); todo(i+1,target-candidates[i]); path.pop_back(); } } };