5079.三个有序数组的交集
解法1:map
思路:
因为是严格递增不存在一个数组中存在两个相同的数
用map存每个数字出现的次数,若该数字次数达到3次添加到结果数组中。
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 
 | class Solution {public:
 vector<int> arraysIntersection(vector<int>& arr1, vector<int>& arr2, vector<int>& arr3) {
 map<int,int> m;
 int n=arr1.size();
 for(int i=0;i<n;i++)
 {
 m[arr1[i]]++;
 m[arr2[i]]++;
 m[arr3[i]]++;
 }
 vector<int> res;
 for(map<int,int>::iterator ite=m.begin();ite!=m.end();ite++)
 {
 if(ite->second==3)
 {
 res.push_back(ite->first);
 }
 }
 return res;
 }
 };
 
 | 
5080.查找两棵二叉搜索树之和
解法1:map
用map存第一棵树对应的target-root->val值,第二颗数查找这个值,若找到直接返回true
即转化为类似的两数之和
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 
 | class Solution {map<int,int> m;
 int tar;
 public:
 bool twoSumBSTs(TreeNode* root1, TreeNode* root2, int target) {
 tar=target;
 midbfs(root1);
 return midbfs2(root2);
 }
 void midbfs(TreeNode *root)
 {
 if(root!=NULL)
 {
 midbfs(root->left);
 m[tar-root->val]++;
 midbfs(root->right);
 }
 }
 bool midbfs2(TreeNode *root)
 {
 if(root!=NULL)
 {
 if(m[root->val]!=0)
 return true;
 return midbfs2(root->left)||midbfs2(root->right);
 }
 return false;
 }
 };
 
 | 
5081.步进数
解法1:预处理+二分
找规律,发现除0-9这10个数,后面的步进数都是从1开始向后遍历加上一位和末位相差1的数,
例如根据1可以向后10,12,根据2可以向后添加21,23。根据这个规律我们就能快速找到所有小于high的步进数。
现在我们要找到从那个步进数开始是大于low的,这样我们可以采用二分查找,找到第一个大于low的或找到步进数的最后一位。
后处理判断找到的值是否大于low,
1.若小于表示在low-high内没有步进数
2.若大于将找到的步进数数组从left到结束添加到结果数组
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 
 | class Solution {public:
 vector<int> countSteppingNumbers(int low, int high) {
 vector<int> res;
 for(int i=0;i<=9;i++){res.push_back(i);}
 int i=1,cur,k,temp;
 while(1)
 {
 cur=res[i];
 k=cur%10;
 if(k-1>=0)
 {
 temp=cur*10+k-1;
 if(temp>high)
 break;
 res.push_back(temp);
 }
 if(k+1<=9)
 {
 temp=cur*10+k+1;
 if(temp>high)
 break;
 res.push_back(temp);
 }
 i++;
 }
 int left=0,right=res.size()-1;
 while(left<right)
 {
 int mid=left+(right-left)/2;
 if(res[mid]<low)
 {
 left=mid+1;
 }
 else right=mid;
 }
 vector<int> anb;
 if(res[left]<low)   return anb;
 vector<int> ans(res.begin()+left,res.end());
 return ans;
 }
 };
 
 | 
5099.验证回文字符串 III
解法1:动态规划
问题的本质就是找一个最长回文子序列。
思路:
先创建一个字符串t是s的翻转字符串。这样我们就可以将问题转为找s和t的最长公共子序列
若最长公共子序列长度>=n-k则符合要求。
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 
 | class Solution {public:
 bool isValidPalindrome(string s, int k) {
 int n=s.size();
 string t=s;
 reverse(t.begin(),t.end());
 vector<vector<int>> dp(n+1,vector<int>(n+1,0));
 for(int i=0;i<n;i++)
 {
 for(int j=0;j<n;j++)
 {
 if(s[i]==t[j])  dp[i+1][j+1]=dp[i][j]+1;
 else    dp[i+1][j+1]=max(dp[i+1][j],dp[i][j+1]);
 }
 }
 return dp[n][n]>=n-k;
 }
 };
 
 |