要知道数组的元素在内存地址中是连续的,不能单独删除数组中的某个元素,只能覆盖。
通过一个快指针和慢指针在一个for循环下完成两个for循环的工作。
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
int n=nums.size();
int slow=0;
for(int fast=0;fast<n;fast++){
if(nums[fast]!=val){//快慢指针判断条件,自己实现起来有点晕
nums[slow]=nums[fast];
slow++;
}
}
return slow;
}
};
class Solution {
public:
int removeDuplicates(vector<int>& nums) {
int n=nums.size();
int slow=0;
for(int fast=1;fast<n;fast++){
if(nums[slow]!=nums[fast]){//当nums[slow]==nums[fast]时,应保留slow的位置,让后面的覆盖它。当两者不等时,才有后面的操作
slow++;//不同之处就先让slow++
nums[slow]=nums[fast];
}
}
return slow+1;
}
};
1、让slow,fast都有等于0
2、如果nums[fast]不等于0,就让nums[fast]覆盖nums[slow],并让slow++
3、将slow及之后的元素赋0
为了定义少一个指针fast,直接for(int num:nums)来遍历
class Solution {
public:
void moveZeroes(vector<int>& nums) {
int slow=0;
int n=nums.size();
for(int num:nums){
if(num!=0){
nums[slow]=num;
slow++;
}
}
while(slow<n){
nums[slow]=0;
slow++;
}
}
};
第一种方法:栈法(字符串当栈来用)。匹配的问题(比如括号问题)都可以考虑栈。
本题确实可以使用栈的思路,但是没有必要使用栈,因为最后比较的时候还要比较栈里的元素,有点麻烦。
class Solution {
public:
bool backspaceCompare(string s, string t) {
string ss;//不用直接用栈,将字符串当栈来用
string tt;
for(int i=0;i<s.size();i++){
if(s[i]!='#') ss+=s[i];//直接串在后面
else if(!ss.empty()) ss.pop_back();//串还有这操作??
}
for(int j=0;j<t.size();j++){
if(t[j]!='#') tt+=t[j];//直接串在后面
else if(!tt.empty()) tt.pop_back();//串还有这操作??
}
if(ss==tt) return true;//直接判断两个字符串是否相等
else return false;
}
};
第二种方法:双指针法
两个字符串都从后往前遍历,记录#的个数,并模拟消除字符
class Solution {
public:
bool backspaceCompare(string s, string t) {
int sSkipnum=0,tSkipnum=0;//记录字符串中#的数量
int i=s.size()-1;
int j=t.size()-1;
while(1){
while(i>=0){
if(s[i]=='#') sSkipnum++;
else{
if(sSkipnum>0) sSkipnum--;//sSkipnum--之后能直接跳到i--,表明已经跃过了#前面的那个符号(模拟消除)
else break;
}
i--;//能到i--前提是不提前break掉
}
while(j>=0){
if(t[j]=='#') tSkipnum++;
else{
if(tSkipnum>0) tSkipnum--;
else break;
}
j--;//能到j--前提是不提前break掉
}
if(i<0 || j<0) break;
if(s[i]!=t[j]) return false;//如果字符不相等,直接返回false
i--;
j--;
}
if(i<0 && j<0) return true;
return false;
}
};
(自己实现时细节差了点东西,见注释)
class Solution {
public:
vector<int> sortedSquares(vector<int>& nums) {
vector<int> res(nums.size(),0);//先把res的大小定义出来,否则后面K--会导致指针的非0偏移量访问
int left=0;
int right=nums.size()-1;
int k=nums.size()-1;
while(left<=right){
if(nums[left]*nums[left]<nums[right]*nums[right]){
res[k]=nums[right]*nums[right];//一开始自己的想法是res.push_back(),在循环结束之后才reverse一下的
k--;
right--;
}
else{
res[k]=nums[left]*nums[left];//直接一开始将k定义到res数组大小,后面不断--,就解决了上面那个问题
k--;
left++;
}
}
return res;
}
};