数组在内存中的储存地址是连续的,不能单独删除某个元素,只能覆盖。
常用方法——双指针法:在一个 for 循环中完成两个 for 循环的工作
1、同向扫描(快慢指针法):指针1 和 指针2 都从头到尾,方向相同,但速度不同,以不同策略移动
2、反向扫描:指针1从头到尾,指针2从尾到头,在中间汇合
一、 LeetCode题 27.移除元素 27. 移除元素 - 力扣(LeetCode)
题目描述:
1、暴力解法
class Solution { public: int removeElement(vector<int>& nums, int val) { int k = 0; for(int i = 0; i < nums.size(); i++){ if(nums[i]!=val){ nums[k] = nums[i]; k++; } } return k; } };
2、快慢指针法
class Solution { public: int removeElement(vector<int>& nums, int val) { int slowIndex = 0; for(int fastIndex = 0; fastIndex < nums.size(); fastIndex++){ if (nums[fastIndex] != val){ nums[slowIndex] = nums[fastIndex]; slowIndex++; } } return slowIndex; } };
3、反向扫描法(优化,避免了需要保留元素的重复赋值):当左边的元素等于目标值时,用右边的元素覆盖
class Solution { public: int removeElement(vector<int>& nums, int val) { int leftIndex = 0; int rightIndex = nums.size() - 1; while (leftIndex <= rightIndex){ if (nums[leftIndex] == val){ nums[leftIndex] = nums [rightIndex]; rightIndex--; } else leftIndex++; } return leftIndex; } };
二、 LeetCode题 283.移动零 283. 移动零 - 力扣(LeetCode)
题目描述:
代码:与上一道题思路类似。
class Solution { public: void moveZeroes(vector<int>& nums) { int slowIndex = 0; int rightIndex = nums.size() - 1; int k = 0; for(int fastIndex = 0; fastIndex < nums.size(); fastIndex++){ if(nums[fastIndex] != 0){ nums[slowIndex] = nums[fastIndex]; slowIndex++; } else k++; } while(k > 0){ nums[nums.size() - k--] = 0; } } };
三、 LeetCode题 844.比较含退格的字符串 844. 比较含退格的字符串 - 力扣(LeetCode)
题目描述:
代码:双指针法,当快指针指向元素为退格字符‘#’,慢指针减一,deleteString 函数返回处理完退格信息的字符串。
class Solution { public: string deleteString(string& s, int n) { int slowIndex = 0; for (int fastIndex = 0; fastIndex < n; fastIndex++) { if (s[fastIndex] != '#') { s[slowIndex] = s[fastIndex]; slowIndex++; } else { if (slowIndex > 0){ slowIndex--; } } } string result; for(int i = 0; i < slowIndex; i++){ result = result + s[i]; } return result; } bool backspaceCompare(string s, string t) { return deleteString(s, s.length()) == deleteString(t, t.length()); } };
力扣官方题解:
定义两个指针,分别指向两字符串的末尾。每次让两指针逆序地遍历两字符串,直到两字符串能够各自确定一个字符,然后将这两个字符进行比较。重复这一过程直到找到的两个字符不相等,或遍历完字符串为止。
class Solution { public: bool backspaceCompare(string S, string T) { int i = S.length() - 1, j = T.length() - 1; int skipS = 0, skipT = 0; while (i >= 0 || j >= 0) { while (i >= 0) { if (S[i] == '#') { skipS++, i--; } else if (skipS > 0) { skipS--, i--; } else { break; } } while (j >= 0) { if (T[j] == '#') { skipT++, j--; } else if (skipT > 0) { skipT--, j--; } else { break; } } if (i >= 0 && j >= 0) { if (S[i] != T[j]) { return false; } } else { if (i >= 0 || j >= 0) { return false; } } i--, j--; } return true; } };
三、 LeetCode题 977.有序数组的平方 977. 有序数组的平方 - 力扣(LeetCode)
题目描述:原数组是有序的,则数组平方的最大值只可能出现在原数组的两端,定义一个新数组逆序保存原数组对应元素平方后的最大值,两个指针分别从前往后和从后往前。
代码:
class Solution { public: vector<int> sortedSquares(vector<int>& nums) { int leftIndex = 0; int rightIndex = nums.size() - 1; int k = rightIndex; vector<int> result(nums.size()); while (leftIndex <= rightIndex) { if (nums[leftIndex] * nums[leftIndex] < nums[rightIndex] * nums[rightIndex]) { result[k--] = nums[rightIndex] * nums[rightIndex]; rightIndex--; } else { result[k--] = nums[leftIndex] * nums[leftIndex]; leftIndex++; } } return result; } };
注意:vector 定义时需要申请空间,没有申请空间时不能直接赋值
本文根据代码随想录顺序刷题。代码随想录 (programmercarl.com)