今天的题目主要是围绕双指针
1.移除元素 27. 移除元素 - 力扣(LeetCode)
这道题如果开辟一个新空间就很简单,如果在原数组上操作就略有难度
1.1最朴素的双for循环
1.2双指针
快指针找新元素,慢指针更新新元素应该插入的地址
int removeElement(vector<int>& nums, int val) {
int slow=0;
for(int fast=0;fast<nums.size();fast++){
if(nums[fast]!=val){
nums[slow]=nums[fast];
slow++;
}
}
return slow;
}
2.删除排序数组中的重复项 26. 删除有序数组中的重复项 - 力扣(LeetCode)
还是相同的思路,快指针找不同的,慢指针更新位置
int removeDuplicates(vector<int>& nums) {
if (nums.empty()) return 0;
int slow = 0;
for (int fast = 1; fast < nums.size(); fast++) {
if (nums[fast] != nums[slow]) {
nums[++slow] = nums[fast];
}
}
return slow + 1;
}
3.移动零 283. 移动零 - 力扣(LeetCode)
移动零其实就是把非零元素放到前面,然后剩下的补0就可以了
void moveZeroes(vector<int>& nums) {
int index=0;
for(int i=0;i<nums.size();i++){
if(nums[i]!=0){
nums[index++]=nums[i];
}
}
for(int i=index;i<nums.size();i++){
nums[i]=0;
}
}
4.有序数组的平方 977. 有序数组的平方 - 力扣(LeetCode)
这道题最简单的方法就是每一个都算出来平方,然后在排序,但是这就太慢了,可以用到双指针,两边一左一右一起往中间走,这样就提高了效率
vector<int> sortedSquares(vector<int>& nums) {
int left = 0, right = nums.size() - 1;
vector<int> ret(nums.size());
int k = right;
while (left <= right && k >= 0) {
int num1 = nums[left] * nums[left];
int num2 = nums[right] * nums[right];
if (num1 > num2) {
++left;
ret[k--] = num1;
} else {
--right;
ret[k--] = num2;
}
}
return ret;
}
5.比较含退格的字符串 844. 比较含退格的字符串 - 力扣(LeetCode)
这道题感觉如果用栈比双指针更好懂一些
是字母就入栈,是#就出栈,然后把栈里面的字母给变成string,比较一下就可以了
bool backspaceCompare(string s, string t) {
auto processString = [](const string& str) {
stack<char> stack;
for (char c : str) {
if (c == '#') {
if (!stack.empty()) {
stack.pop();
}
} else {
stack.push(c);
}
}
string result = "";
while (!stack.empty()) {
result = stack.top() + result;
stack.pop();
}
return result;
};
return processString(s) == processString(t);
}
6.螺旋矩阵系列
6.1正方形矩阵59. 螺旋矩阵 II - 力扣(LeetCode)
这个就是分解成相互嵌套的正方环形就可以了,主要还是模拟
int cur = 1;
void deal(std::vector<std::vector<int>>& ans, int i, int n) {
if (i == 1) {
ans[n / 2][n / 2] = cur++;
} else {
int delt = (n - i) / 2;
int k = delt + i - 1;
for (int j = delt; j <= k; ++j) {
ans[delt][j] = cur++;
}
for (int j = delt + 1; j <= k; ++j) {
ans[j][k] = cur++;
}
for (int j = k - 1; j >= delt; --j) {
ans[k][j] = cur++;
}
for (int j = k - 1; j > delt; --j) {
ans[j][delt] = cur++;
}
}
}
std::vector<std::vector<int>> generateMatrix(int n) {
std::vector<std::vector<int>> ans(n, std::vector<int>(n));
for (int i = n; i > 0; i -= 2) {
deal(ans, i, n);
}
return ans;
}
6.2长方形矩阵顺指针元素输出 54. 螺旋矩阵 - 力扣(LeetCode)
这个题目也是模拟,找到规律就好了
class Solution {
public:
vector<int> spiralOrder(vector<vector<int>>& matrix) {
vector<int> ans;
if (matrix.empty()) return ans;
int top = 0, bottom = matrix.size() - 1;
int left = 0, right = matrix[0].size() - 1;
while (top <= bottom && left <= right) {
for (int i = left; i <= right; ++i) {
ans.push_back(matrix[top][i]);
}
top++;
for (int i = top; i <= bottom; ++i) {
ans.push_back(matrix[i][right]);
}
right--;
if (top <= bottom) {
for (int i = right; i >= left; --i) {
ans.push_back(matrix[bottom][i]);
}
bottom--;
}
if (left <= right) {
for (int i = bottom; i >= top; --i) {
ans.push_back(matrix[i][left]);
}
left++;
}
}
return ans;
}
};
这个相当于是一个四指针,规定了四个方向的范围
今天的学习就结束啦!!!给大家推荐一个网站代码随想录 很适合初学者进行系统性的学习和刷题,有详细的讲解以及相关习题推荐。