1.有序数组的平方
给你一个按 非递减顺序 排序的整数数组 nums,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。
class Solution {
public:
vector<int> sortedSquares(vector<int>& nums) {
int l = 0, h = nums.size() - 1;
vector<int> result(h + 1);
int index = h;
while (l <= h) {
int low = nums[l] * nums[l];
int high = nums[h] * nums[h];
if (low > high) {
result[index--] = low;
l++;
}
else {
result[index--] = high;
h--;
}
}
return result;
}
};
- 第一次错误解答,在原数组上进行操作, 破坏了相对顺序位置
class Solution {
public:
vector<int> sortedSquares(vector<int>& nums) {
// 1.看到第一眼的想法,先平方再排序
// 2. 可以使用双指针的方法,从两端的平方一直取最大值
int l=0, h=nums.size() - 1;
vector<int> result(h+1);
while(l <= h){
int low = nums[l] * nums[l];
int high = nums[h] * nums[h];
// 1。下面的操作会改变头部和尾部元素平方大小的排序相对顺序,因此出错
if(low > high){
int temp = nums[h];
nums[h] = low;
nums[l] = t
}
else{
nums[h] = high;
}
h--;
}
return nums;
}
};
2.长度最小的子数组(第一遍用双指针方法写错了,看了答案才做对)
给定一个含有 n 个正整数的数组和一个正整数 target 。
找出该数组中满足其和 ≥ target 的长度最小的 连续子数组 [numsl, numsl+1, …, numsr-1, numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0 。
- 注意点
- 双指针法在这道题中慢指针和快指针在什么条件下分别前进
- 计算距离
class Solution {
public:
int minSubArrayLen(int target, vector<int>& nums) {
int i=0, sum=0;
// int min=nums.size();
int min = INT32_MAX;
bool flag = false;
for(int j=0; j<nums.size(); j++){
sum += nums[j]; // 下面while循环已经将sum的值减小到小于target了
// if(sum < target){
//sum += nums[j];
//}
while(sum >= target){
flag = true;
int distance = j - i + 1;
min = min < distance ? min : distance;
/*
if(distance < min){
min = distance;
}*/
// sum -= nums[i];
sum -= nums[i++];
}
}
if(flag){
return min;
}
return 0;
}
};
2.1拓展题
- 水果成篮
哈希与双指针的结合
class Solution {
public:
int totalFruit(vector<int>& fruits) {
int n = fruits.size();
unordered_map<int, int> cnt;
int left = 0, ans = 0;
for(int right = 0; right < n; ++right){
++cnt[fruits[right]];
while(cnt.size() > 2){
auto it = cnt.find(fruits[left]);
--it->second;
if(it->second == 0){
cnt.erase(it);
}
++left;
}
ans = max(ans, right-left+1);
}
return ans;
}
};
给你一个字符串 s 、一个字符串 t 。返回 s 中涵盖 t 所有字符的最小子串。如果 s 中不存在涵盖 t 所有字符的子串,则返回空字符串 “” 。
注意:
对于 t 中重复字符,我们寻找的子字符串中该字符数量必须不少于 t 中该字符数量。
如果 s 中存在这样的子串,我们保证它是唯一的答案。
class Solution {
public:
unordered_map<char, int> ori, cnt;
bool check(){
for(auto &s : ori){
if(cnt[s.first] < s.second){
return false;
}
}
return true;
}
string minWindow(string s, string t) {
for(const auto & c : t){
++ori[c];
}
int l = 0, r = 0;
int len = INT_MAX, ansL = -1;
while(r < s.size()){
if(ori.find(s[r]) != ori.end()){ // 当前遍历的字符 在t中
++cnt[s[r]];
}
while(check() && l<=r){ // 如果已经找到了满足条件的 子串
if(r - l + 1 < len){
len = r - l + 1;
ansL = l; // 记录满足条件的子串的左边界
}
if(ori.find(s[l]) != ori.end()){
--cnt[s[l]];
}
++l;
}
r++;
}
return ansL == -1 ? string() : s.substr(ansL, len);
}
};
3.螺旋矩阵
给你一个正整数 n ,生成一个包含 1 到 n2 所有元素,且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix 。
- 注意点:
- 奇数大小的需要单独对矩阵中心点进行处理
- 需要预判出一共需要循环多少圈 以及 每一圈的大小
class Solution {
public:
vector<vector<int>> generateMatrix(int n) {
// 如果是n的平方,那么二维数组就是n行n列
// 没循环完外面一圈内部就会剩下 n-2行列元素
// 1. 先得知道一共得循环多少圈 a = n // 2 + (n%2)
// 2. 计算当前圈有多大 b = n - a
vector<vector<int>> result(n, vector<int>(n, 0));
int x = 0, y = 0, num = 1;
for (int i = 0; i < n / 2 + (n % 2); i++) { // i代表了圈数
for (int a = i; a < (n - i)-1; a++) { //第一行 // n-i代表了外圈大小
result[i][a] = num++;
x = i;
y = a;
cout << "[" << x << ", " << y << "]" << "-" << num << " ";
}
cout << endl;
for (int b = i; b < (n - i)-1; b++) {
result[b][n-i- 1] = num++;
x = b;
y = n - i - 1;
cout << "[" << x << ", " << y << "]" << "-" << num << " ";
}
cout << endl;
for (int c =(n-i)-1; c > i; c--) {
result[n - i - 1][c] = num++;
x = n - i - 1;
y = c;
cout << "[" << x << ", " << y << "]" << "-" << num << " ";
}
cout << endl;
for (int d = (n - i - 1); d > i; d--) {
result[d][i] = num++;
x = d;
y = i;
cout << "[" << x << ", " << y << "]" << "-" << num << " ";
}
cout << endl;
}
if (n % 2 == 1) {
int middle = n / 2;
result[middle][middle] = n * n;
}
return result;
}
};