单序列双指针篇
3.1 反转字符串
本质是相向双指针。
344. 反转字符串
code
class Solution {
public:
void reverseString(vector<char>& s) {
int n = s.size();
int l = 0, r = n - 1;
char tmp;
while (l < r) {
tmp = s[r];
s[r] = s[l];
s[l] = tmp;
l++;
r--;
}
return;
}
};
3794. 反转字符串前缀
给你一个字符串 s 和一个整数 k。
反转 s 的前 k 个字符,并返回结果字符串。
code
class Solution {
public:
string reversePrefix(string s, int k) {
for (int l = 0, r = k - 1; l < r; l++, r--) {
swap(s[l], s[r]);
}
return s;
}
};
2000. 反转单词前缀 1199
给一个下标从0开始的字符串word 和一个字符 ch 。
找出ch第一次出现的下标i, 反转word 中从下标0开始, 到下标i 结束的那段字符。不存在ch 则不反转。
code
class Solution {
public:
string reversePrefix(string word, char ch) {
int i = word.find(ch);
if (i != string::npos) {
for (int l = 0, r = i; l < r; l++, r--) {
swap(word[l], word[r]);
}
}
return word;
}
};
3643. 垂直翻转子矩阵 1235
题意:给一个大矩阵, 给出子矩阵左上角坐标和边长(正方形), 按行对这个正方形矩阵反转。
code
class Solution {
public:
vector<vector<int>> reverseSubmatrix(vector<vector<int>>& grid, int x,
int y, int k) {
int m = grid.size(), n = grid[0].size();
for (int i = x; i < x + k / 2; i++) {
for (int j = y; j < y + k; j++) {
swap(grid[i][j], grid[x + x + k - 1 - i][j]);
}
}
return grid;
}
};
832. 翻转图像 1243
题意:给一个nxn的二进制矩阵image, 先水平翻转图像,然后反转图像并返回结果。
反转意思是0变1 , 1 变0 。
code
class Solution {
public:
vector<vector<int>> flipAndInvertImage(vector<vector<int>>& image) {
int m = image.size(), n = image[0].size();
for (int i = 0; i < m; i++) {
for (int j = 0; j < n / 2; j++) {
swap(image[i][j], image[i][n - 1 - j]);
image[i][j] = !image[i][j];
image[i][n - 1 - j] = !image[i][n - 1 - j];
}
if (n % 2 == 1)
image[i][n / 2] = !image[i][n / 2];
}
return image;
}
};
3823. 反转一个字符串里的字母后反转特殊字符 1250
题意:给一个小写英文字母和特殊字符组成的字符串s 。 任务是按顺序执行以下操作:
- 反转小写字母, 并放回原来字母位置
- 反转特殊字符, 放回。
写法上还可以再优化下。
code
class Solution {
public:
bool isLetter(char c) { return 'a' <= c && c <= 'z'; }
string reverseByType(string s) {
int n = s.size();
int letter_l = 0, letter_r = n - 1;
int special_l = 0, special_r = n - 1;
while (true) {
while(letter_l < n && !isLetter(s[letter_l])) letter_l++;
while(letter_r >= 0 && !isLetter(s[letter_r])) letter_r--;
if(letter_l >= letter_r) break;
swap(s[letter_l], s[letter_r]);
letter_l++; letter_r--;
}
while(true){
while(special_l < n && isLetter(s[special_l])) special_l++;
while(special_r >= 0 && isLetter(s[special_r])) special_r--;
if(special_l >= special_r) break;
swap(s[special_l], s[special_r]);
special_l++;special_r--;
}
return s;
}
};
541. 反转字符串 II
题意: 给一个字符串s 和 一个整数 k ,从字符串开头算起,每计数至 2k 个字符, 就反转这2k 字符中 前k 个字符。
剩余字符少于 k 个 就全部反转。
剩余字符小于 2k 但 大于等于k个, 则反转前k 个字符。其余保持原样。
太优雅了灵神
code
class Solution {
public:
string reverseStr(string s, int k) {
int n = s.size();
for (int i = 0; i < n; i += k * 2) {
reverse(s.begin() + i, s.begin() + min(i + k, n));
}
return s;
}
};
557. 反转字符串中的单词 III
给一个s, 反转每个单词的字符顺序。
code
class Solution {
public:
string reverseWords(string s) {
int n = s.size();
for (int i = 0; i < n; i++) {
int r = s.find(' ', i);
r = (r == string::npos ? n : r);
reverse(s.begin() + i, s.begin() + r);
i = r;
}
return s;
}
};
151. 反转字符串中的单词
题意: 给一个字符串s,反转其中单词顺序。
先整个字符串反转,再对每个单词做反转即可。 注意,反转后的字符串不能有前后的空格。还要处理中间多余的空格。
时间、空间O(n)不知道有没有更简洁的写法。
code
class Solution {
public:
string reverseWords(string s) {
reverse(s.begin(), s.end());
int n = s.size();
int write = 0;
int r;
for (int i = 0; i < n; i = r + 1) {
while (i < n && s[i] == ' ')
i++;
if (i >= n)
break;
if (write > 0)
s[write++] = ' ';
r = s.find(' ', i);
r = (r == string::npos ? n : r);
int start = write;
for (int j = i; j < r; j++)
s[write++] = s[j];
reverse(s.begin() + start, s.begin() + write);
}
s.resize(write);
return s;
}
};
3775. 反转元音数相同的单词 1392
题意:给一个s ,小写英文单词组成。 单词之间一个空格隔开。
确定第一个单词中的元音字母数。后续每个单词,如果元音字母数和第一个相同,将他们反转。
返回处理后的字符串。
code
class Solution {
public:
bool isVol(char c) {
string vowels = "aeiou";
return vowels.find(c) != string::npos;
}
string reverseWords(string s) {
int n = s.size();
int l = 0, r = s.find(' ');
int volCnt = 0;
for (int i = 0; i < r; i++) {
if (isVol(s[i]))
volCnt++;
}
for (int i = r + 1; i < n; i = r + 1) {
r = s.find(' ', i);
r = (r == string::npos ? n : r);
int cnt = 0;
for (int j = i; j < r; j++) {
if (isVol(s[j]))
cnt++;
}
if (cnt == volCnt) {
reverse(s.begin() + i, s.begin() + r);
}
}
return s;
}
};
917. 仅仅反转字母
题意:给一个s, 根据下述规则反转字符串。
- 非英文字母保留原来位置。
- 英文字母位置反转。
code
class Solution {
public:
bool isLetter(char c) {
return c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z';
}
string reverseOnlyLetters(string s) {
int n = s.size();
int l = 0, r = n - 1;
while (l < r) {
while (l < n && !isLetter(s[l]))
l++;
while (r >= 0 && !isLetter(s[r]))
r--;
if (l < r) {
swap(s[l], s[r]);
l++;
r--;
}
}
return s;
}
};
345. 反转字符串中的元音字母
题意: 给一个s,仅反转所有元音字母。
code
class Solution {
public:
bool isVol(char c) {
string volwels = "aeiouAEIOU";
return volwels.find(c) != string::npos;
}
string reverseVowels(string s) {
int n = s.size();
int l = 0, r = n - 1;
while (l < r) {
while (l < n && !isVol(s[l]))
l++;
while (r >= 0 && !isVol(s[r]))
r--;
if (l < r) {
swap(s[l], s[r]);
l++;
r--;
}
}
return s;
}
};
反转字符串的章节就结束了,明天准备开始相向双指针的章节。
基本思路是从数组的两端开始向中间移动。大部分例子在1800分以下,两题2200分以上。
3.2 相向双指针
2697. 字典序最小回文串 1304
题意: 给一个小写英文字母组成的字符串s,可以执行一些操作。用其他小写字母替换s中一个字符 。
让s 变成一个回文串。 最少操作。不止一种 则 选取字典序最小的。 返回最终的回文串。
code
class Solution {
public:
string makeSmallestPalindrome(string s) {
int n = s.size();
for (int i = 0; i < n / 2; i++) {
if (s[i] != s[n - 1 - i]) {
s[i] = min(s[i], s[n - 1 - i]);
s[n - 1 - i] = s[i];
}
}
return s;
}
};
125. 验证回文串
所有大写转小写,移除非字母数字字符后,是回文串。判断是否是回文。
code
class Solution {
public:
bool isNormalChar(char c) {
return (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') ||
(c >= 'A' && c <= 'Z');
}
bool isPalindrome(string s) {
int n = s.size();
for (int l = 0, r = n - 1; l < r; l++, r--) {
while (l < n && !isNormalChar(s[l]))
l++;
while (r >= 0 && !isNormalChar(s[r]))
r--;
if (l < r) {
if (s[l] >= 'A' && s[l] <= 'Z')
s[l] += 32;
if (s[r] >= 'A' && s[r] <= 'Z')
s[r] += 32;
if (s[l] != s[r])
return false;
}
}
return true;
}
};
1750. 删除字符串两端相同字符后的最短长度 1502
题意:给一个 由 a b c组成的字符串s, 可以执行下面操作 任意次
- 选择 s 的一个非空前缀,这个前缀所有字符相同
- 选择 s 的一个非空后缀,这个后缀所有字符相同
- 前缀和后缀在字符串中任意位置不能有交集
- 前缀和后缀包含所有字符要相同
- 同时删除前缀和后缀
返回对s执行任意次操作后,能得到的最短长度。
code
class Solution {
public:
int minimumLength(string s) {
int n = s.size();
int cnt = 0;
int l = 0, r = n - 1;
while (l < r && s[l] == s[r]) {
char c = s[l];
while (l <= r && s[l] == c) {
l++;
}
while (l <= r && s[r] == c) {
r--;
}
}
return r - l + 1;
}
};
2105. 给植物浇水 II 1507
题意:A和B 给n 个植物浇水,左往右编号0-n-1, 其中,第i株植物位置时 x = i
... 题目太长了,简要说。
俩人从两边往中间浇水。 每个植物浇水时间相同,需要浇水的量不同。
水够的话必须浇水,否则必须重新灌水。
俩人一起到达一植物,谁水多谁浇。一样多A浇
给一个plants 表示需要的水量。 另外 capacityA 和 capacityB 表示俩人水罐容量。
问重新灌水次数。
双指针模拟即可?
code
class Solution {
public:
int minimumRefill(vector<int>& plants, int capacityA, int capacityB) {
int n = plants.size();
int l = 0, r = n - 1;
int curA = capacityA, curB = capacityB, res = 0;
while (l <= r) {
if (l == r) {
if (max(curA, curB) < plants[l])
res++;
break;
}
if(curA < plants[l]){res++; curA = capacityA - plants[l];}
else { curA -= plants[l];}
if(curB < plants[r]){ res++; curB = capacityB - plants[r];}
else {curB -= plants[r];}
l++;
r--;
}
return res;
}
};
977. 有序数组的平方 做到 O(n)
题意:给一个按照非递减数组 nums,返回每个数字的平方组成的新数组。要求也按照非递减顺序排列。
code
class Solution {
public:
vector<int> sortedSquares(vector<int>& nums) {
vector<int> res;
int n = nums.size();
int l = 0 , r = n-1 ;
int cnt = 0;
while(cnt < n){
if(abs(nums[l]) >= abs(nums[r]) ){
res.push_back(nums[l] * nums[l]);
l++;
cnt++;
}else {
res.push_back(nums[r] * nums[r]);
r--;
cnt++;
}
}
reverse(res.begin(), res.end());
return res;
}
};
658. 找到 K 个最接近的元素
code
class Solution {
public:
vector<int> findClosestElements(vector<int>& arr, int k, int x) {
vector<int> res;
int n = arr.size();
int l = 0, r = n - 1;
while (l <= r) {
if (abs(x - arr[l]) > abs(x - arr[r])) {
res.push_back(arr[l]);
l++;
} else {
res.push_back(arr[r]);
r--;
}
}
reverse(res.begin(), res.end());
res.resize(k);
sort(res.begin(), res.end());
return res;
}
};
1471. 数组中的 K 个最强值
code
class Solution {
public:
vector<int> getStrongest(vector<int>& arr, int k) {
int n = arr.size();
sort(arr.begin(), arr.end());
int m = arr[(n - 1) / 2];
int l = 0, r = n - 1;
vector<int> res;
while (l <= r) {
if (abs(arr[l] - m) > abs(arr[r] - m)) {
res.push_back(arr[l]);
l++;
} else if(abs(arr[l] - m) < abs(arr[r] - m)) {
res.push_back(arr[r]);
r--;
} else {
if(arr[l] >= arr[r]) {
res.push_back(arr[l]);
l++;
}else {
res.push_back(arr[r]);
r--;
}
}
}
res.resize(k);
return res;
}
};
后面对于无争议的题不再写题意,直接给出代码了。
167. 两数之和 II - 输入有序数组
code
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
int n = nums.size();
int l = 0, r = n - 1;
vector<int> res;
while (l < r) {
if (nums[l] + nums[r] == target)
return {l + 1, r + 1};
if (nums[l] + nums[r] > target) {
r--;
} else {
l++;
}
}
return res;
}
};
633. 平方数之和
code
class Solution {
public:
bool judgeSquareSum(int c) {
int a = 0, b = sqrt(c);
while (a <= b) {
if (a * a == c - b * b)
return true;
if (a * a < c - b * b) {
a++;
} else {
b--;
}
}
return false;
}
};
2824. 统计和小于目标的下标对数目 非暴力做法
code
class Solution {
public:
int countPairs(vector<int>& nums, int target) {
int n = nums.size();
int res = 0;
int l = 0, r = n - 1;
sort(nums.begin(), nums.end());
// -1 1 1 2 3
while (l < r) {
if (nums[l] + nums[r] >= target)
r--;
else {
res+= (r-l);
l++;
}
}
return res;
}
};
LCP 28. 采购方案 同 2824 题
code
class Solution {
public:
long long MOD = 1e9 + 7;
int purchasePlans(vector<int>& nums, int target) {
int n = nums.size();
int l = 0, r = n - 1;
int res = 0;
sort(nums.begin(), nums.end());
while (l < r) {
if (nums[l] + nums[r] <= target) {
res = (res + (r - l)) % MOD;
l++;
} else {
r--;
}
}
return res;
}
};
16. 最接近的三数之和
ps : max 要/2 防止负数溢出。 另外还有些剪枝操作可以做用来优化。
code
class Solution {
public:
int threeSumClosest(vector<int>& nums, int target) {
int n = nums.size();
sort(nums.begin(), nums.end());
// -4, -1, 1, 2
int res = INT_MAX/2;
for (int i = 0; i < n - 2; i++) {
int l = i + 1, r = n - 1;
while (l < r) {
int sum = nums[i] + nums[l] + nums[r];
if( sum == target) return target;
if (abs(sum - target) < abs(res - target)) {
res = sum;
}
if (sum > target)
r--;
else
l++;
}
}
return res;
}
};
15. 三数之和
code
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
int n = nums.size();
vector<vector<int>> res;
sort(nums.begin(), nums.end());
for (int i = 0; i < n - 2; i++) {
int x = nums[i];
if (i && x == nums[i - 1])
continue;
int j = i + 1, k = n - 1;
while (j < k) {
if (x + nums[j] + nums[k] == 0) {
res.push_back({x, nums[j], nums[k]});
for (j++; j < k && nums[j] == nums[j - 1]; j++);
for (k--; k > j && nums[k] == nums[k + 1]; k--);
}
else if (x + nums[j] + nums[k] > 0) {
k--;
} else {
j++;
}
}
}
return res;
}
};
18. 四数之和
ps:需要处理越界问题
code
class Solution {
public:
vector<vector<int>> fourSum(vector<int>& nums, int target) {
int n = nums.size();
sort(nums.begin(), nums.end());
vector<vector<int>> res;
for (int a = 0; a < n - 3; a++) {
long long x = nums[a];
if(a > 0 && x == nums[a-1]) continue;
long long tar = target - x;
for (int b = a + 1; b < n - 2; b++) {
long long y = nums[b];
tar = target - x - y;
if(b > a+1 && y == nums[b-1]) continue;
int c = b + 1, d = n - 1;
while (c < d) {
if (nums[c] + nums[d] == tar) {
res.push_back({(int)x,(int)y, nums[c], nums[d]});
for (c++; c < d && nums[c] == nums[c - 1]; c++);
for (d--; d > c && nums[d] == nums[d + 1]; d--);
} else if (nums[c] + nums[d] > tar) {
d--;
} else {
c++;
}
}
}
}
return res;
}
};
- 数的平方等于两数乘积的方法数 1594
code
class Solution {
public:
int numTriplets(vector<int>& nums1, vector<int>& nums2) {
int l1 = nums1.size(), l2 = nums2.size();
int res = 0;
sort(nums1.begin(), nums1.end());
sort(nums2.begin(), nums2.end());
for (int i = 0; i < l1; i++) {
long long target = (long long) nums1[i] * nums1[i];
int l = 0, r = l2 - 1;
while (l < r) {
long long x = 1LL * nums2[l] * nums2[r];
if (x == target) {
if (nums2[l] == nums2[r]) {
int cnt = r - l + 1;
res += cnt * (cnt - 1) / 2;
break;
} else {
int cnt1 = 1, cnt2 = 1;
while (nums2[l + 1] == nums2[l])
l++, cnt1++;
while (nums2[r - 1] == nums2[r])
r--, cnt2++;
res += cnt1 * cnt2;
l++, r--;
}
} else if (x < target) {
l++;
} else {
r--;
}
}
}
for (int i = 0; i < l2; i++) {
long long target = (long long)nums2[i] * nums2[i];
int l = 0, r = l1 - 1;
while (l < r) {
long long x = 1LL * nums1[l] * nums1[r];
if (x == target) {
if (nums1[l] == nums1[r]) {
int cnt = r - l + 1;
res += cnt * (cnt - 1) / 2;
break;
} else {
int cnt1 = 1, cnt2 = 1;
while (nums1[l + 1] == nums1[l])
l++, cnt1++;
while (nums1[r - 1] == nums1[r])
r--, cnt2++;
res += cnt1 * cnt2;
l++, r--;
}
} else if (x < target) {
l++;
} else {
r--;
}
}
}
return res;
}
};
3862. 找出最小平衡下标 1697
code
class Solution {
public:
int smallestBalancedIndex(vector<int>& nums) {
int n = nums.size();
long long sum = 0, mul = 1;
int l = 0, r = n - 1;
while (l < r) {
if (sum < mul) {
sum += nums[l++];
} else {
if (mul > (long long)1e14 / nums[r]) {
return -1;
}
mul *= nums[r--];
}
}
return sum == mul ? l : -1;
}
};
611. 有效三角形的个数
code
class Solution {
public:
int triangleNumber(vector<int>& nums) {
int res = 0;
sort(nums.begin(), nums.end());
int l, r;
for (int k = 2; k < nums.size(); k++) {
int c = nums[k];
l = 0;
r = k - 1;
while (l < r) {
if (nums[l] + nums[r] > c) {
res += (r-l);
r--;
} else {
l++;
}
}
}
return res;
}
};
923. 三数之和的多种可能 1711
code
class Solution {
public:
int threeSumMulti(vector<int>& nums, int target) {
int mod = 1e9 + 7;
long long res = 0;
int n = nums.size();
sort(nums.begin(), nums.end());
for (int i = 0; i < n - 2; i++) {
if (nums[i] + nums[i + 1] + nums[i + 2] > target)
break;
if (nums[i] + nums[n - 2] + nums[n - 1] < target)
continue;
int l = i + 1, r = n - 1;
while (l < r) {
int sum = nums[i] + nums[l] + nums[r];
if (sum < target) {
l++;
} else if (sum > target) {
r--;
} else {
if (nums[l] == nums[r]) {
res += (r - l + 1) * (r - l) / 2;
res %= mod;
break;
}
int cntl = 1, cntr = 1;
while (l < r && nums[l] == nums[l + 1]) {
l++;
cntl++;
}
while (r > l && nums[r - 1] == nums[r]) {
r--;
cntr++;
}
res += (long)cntl * cntr;
res %= mod;
l++;
r--;
}
}
}
return (int)(res % mod);
}
};
2563. 统计公平数对的数目 1721
code
class Solution {
public:
long long countFairPairs(vector<int>& nums, int lower, int upper) {
int n = nums.size();
long long res = 0;
sort(nums.begin(), nums.end());
int l = n, r = n;
for (int j = 0; j < n; j++) {
while (r && nums[r - 1] > upper - nums[j]) {
r--;
}
while (l && nums[l - 1] >= lower - nums[j]) {
l--;
}
res += min(r, j) - min(l, j);
}
return res;
}
};
948. 令牌放置 1762
code
class Solution {
public:
int bagOfTokensScore(vector<int>& tokens, int power) {
int n = tokens.size();
int res = 0;
sort(tokens.begin(), tokens.end());
int l = 0, r = n - 1;
int score = 0;
while (l <= r) {
if (power >= tokens[l]) {
power -= tokens[l++];
score++;
} else {
if (score == 0)
break;
res = max(score, res);
score--;
power += tokens[r--];
}
}
return max(res,score);
}
};
11. 盛最多水的容器
code
class Solution {
public:
int maxArea(vector<int>& height) {
int n = height.size();
int l = 0, r = n - 1;
int res = 0;
while (l < r) {
int cur = (r - l) * min(height[l], height[r]);
res = max(res, cur);
if (height[l] <= height[r]) {
l++;
} else {
r--;
}
}
return res;
}
};
42. 接雨水
code
class Solution {
public:
int trap(vector<int>& height) {
int res = 0;
int n = height.size();
int pre_max = 0, suf_max = 0;
int l = 0, r = n - 1;
while (l < r) {
pre_max = max(pre_max, height[l]);
suf_max = max(suf_max, height[r]);
if (pre_max < suf_max) {
res += pre_max - height[l];
l++;
} else {
res += suf_max - height[r];
r--;
}
}
return res;
}
};
1616. 分割两个字符串得到回文串 1868
code
class Solution {
public:
bool isPalindrome(string& s, int i, int j) {
while (i < j && s[i] == s[j]) {
i++;
j--;
}
return i >= j;
}
bool check(string& a, string& b) {
int i = 0, j = a.length() - 1;
while (i < j && a[i] == b[j]) {
i++;
j--;
}
return isPalindrome(a, i, j) || isPalindrome(b, i, j);
}
bool checkPalindromeFormation(string a, string b) {
return check(a, b) || check(b, a);
}
};
1498. 满足条件的子序列数目 2276
1782. 统计点对的数目 2457
1861. 旋转盒子 1537
3814. 预算下的最大总容量 1796
3.3 同向双指针
2200. 找出数组中的所有 K 近邻下标 做到 O(n)
code
class Solution {
public:
vector<int> findKDistantIndices(vector<int>& nums, int key, int k) {
vector<int> ans;
int n = nums.size(), j = 0;
for (int i = 0; i < n; i++) {
if (nums[i] != key) {
continue;
}
j = max(j, i - k); // j 至少是 i-k
while (j <= min(i + k, n - 1)) { // j 至多是 i+k,但不能越界
ans.push_back(j++);
}
}
return ans;
}
};
611. 有效三角形的个数
3649. 完美对的数目 1716
1871. 跳跃游戏 VII 1896 做法不止一种
1574. 删除最短的子数组使剩余数组有序 1932
2972. 统计移除递增子数组的数目 II 2153
2122. 还原原数组 2159
2234. 花园的最大总美丽值 2562
581. 最短无序连续子数组
3.4 背向双指针
1793. 好子数组的最大分数 1946
976. 三角形的最大周长 思考题:改成最小周长(原题不是背向双指针,思考题是)
3.5 原地修改
27. 移除元素
26. 删除有序数组中的重复项
80. 删除有序数组中的重复项 II
2273. 移除字母异位词后的结果数组
3684. 至多 K 个不同元素的最大和
283. 移动零
905. 按奇偶排序数组
922. 按奇偶排序数组 II
3467. 将数组按照奇偶性转化
2460. 对数组执行操作
1089. 复写零
75. 颜色分类
2784. 检查数组是否是好的
442. 数组中重复的数据
448. 找到所有数组中消失的数字
1920. 基于排列构建数组
41. 缺失的第一个正数
四、双序列双指针
4.1 双指针
2109. 向字符串添加空格 1315
code
class Solution {
public:
string addSpaces(string s, vector<int>& spaces) {
int n = spaces.size();
string res = "";
int j = 0;
for(int i =0;i < s.size();i++){
if(j < n){
if(spaces[j] == i){
res+=" ";
j++;
}
}
res += s[i];
}
return res;
}
};
2540. 最小公共值 做到 O(n+m)
code
class Solution {
public:
int getCommon(vector<int>& nums1, vector<int>& nums2) {
int len1 = nums1.size(), len2 = nums2.size();
for (int l1 = 0, l2 = 0; l1 < len1 && l2 < len2;) {
if(nums1[l1] == nums2[l2]) return nums1[l1];
else if(nums1[l1] < nums2[l2]) l1++;
else l2++;
}
return -1;
}
};
350. 两个数组的交集 II 解决进阶问题
code
class Solution {
public:
vector<int> intersect(vector<int>& nums1, vector<int>& nums2) {
int cnt1[1001],cnt2[1001];
memset(cnt1,0,sizeof(cnt1));
memset(cnt2,0,sizeof(cnt2));
int len1 = nums1.size(),len2=nums2.size();
vector<int> ans;
for(int i=0;i<len1;i++)
cnt1[nums1[i]]++;
for(int i=0;i<len2;i++)
cnt2[nums2[i]]++;
for(int i=0;i<=1000;i++){
if(cnt1[i]!=0&&cnt2[i]!=0)
for(int j=0;j<min(cnt1[i],cnt2[i]);j++)
ans.push_back(i);
}
return ans;
}
};
88. 合并两个有序数组 做到 O(n+m)
code
class Solution {
public:
void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
int l1 = 0, l2=0 ;
int sorted[m+n];
int now;
while(l1<m||l2<n){
if(l1==m){
now = nums2[l2++];
}else if(l2==n){
now = nums1[l1++];
}
else if(nums1[l1]<nums2[l2]){
now = nums1[l1++];
}else{
now = nums2[l2++];
}
sorted[l1+l2-1] = now;
}
for (int i = 0; i != m + n; ++i) {
nums1[i] = sorted[i];
}
}
};
2570. 合并两个二维数组 - 求和法 做到 O(n+m)
code
class Solution {
public:
vector<vector<int>> mergeArrays(vector<vector<int>>& nums1,
vector<vector<int>>& nums2) {
int l1 = nums1.size(), l2 = nums2.size();
vector<vector<int>> res;
for (int i1 = 0, i2 = 0; i1 < l1 || i2 < l2;) {
if (i1 == l1)
res.push_back(nums2[i2++]);
else if (i2 == l2)
res.push_back(nums1[i1++]);
else {
if (nums1[i1][0] == nums2[i2][0]) {
res.push_back({nums1[i1][0], nums1[i1][1] + nums2[i2][1]});
i1++;
i2++;
} else if (nums1[i1][0] < nums2[i2][0]) {
res.push_back(nums1[i1++]);
} else {
res.push_back(nums2[i2++]);
}
}
}
return res;
}
};
LCP 18. 早餐组合
code
class Solution {
public:
int breakfastNumber(vector<int>& staple, vector<int>& drinks, int x) {
int mod = 1e9 + 7;
int n1 = staple.size(), n2 = drinks.size();
int res = 0;
sort(staple.begin(), staple.end());
sort(drinks.begin(), drinks.end());
int i = 0, j = n2 - 1;
while( i < n1 && j >= 0){
if( staple[i] + drinks[j] <= x ){
res += j+1;
res %=mod;
i+=1;
}else {
j-=1;
}
}
return res % mod;
}
};
1855. 下标对中的最大距离 1515
code
class Solution {
public:
int maxDistance(vector<int>& nums1, vector<int>& nums2) {
int l1 = nums1.size(), l2 = nums2.size();
int res = 0;
int i = 0;
for (int j = 0; j < l2; j++) {
while (i < l1 && nums1[i] > nums2[j]) {
i++;
}
if (i == nums1.size()) {
break;
}
res = max(res, j - i);
}
return res;
}
};
浙公网安备 33010602011771号