必须要注意的算法坑点

第一,在遍历数组时或容器时

尤其是在for()循环的语句块中要改变 i 的值时,一定要注意在for()循环的三个语句中是否有必要写变量自增与自减的语句。

class Solution {
public:
    int lengthOfLastWord(string s) {
        int ans=0;
        for(int i=s.size()-1;i>=0;  ){//此处空着,在循环体内写变量变化的语句
            if(s[i]==' '){
                i--;
            }
            else{
                while(i>=0&&s[i]!=' '){
                    ans++;
                    i--;
                }
                break;
            }
        }
        return ans;
    }
};

2021/1/21补充
今天在做力扣1422. Maximum Score After Splitting a String时,在倒着遍历给定的串s,给数组cnt1中的元素进行赋值时,出现了内存溢出错误。

class Solution {
public:
    int maxScore(string s) {
        int cnt0[5100]={0},cnt1[5100]={0};
        int now=0;
        for(int i=0;i<s.size();i++){
            if(s[i]=='0') now++;
            cnt0[i]=now;
        }
        now=0;
        for(int i=s.size()-1;i>0;i++){//出错点
            if(s[i]=='1') now++;
            cnt1[i]=now;
        }
        int ans=-1;
        for(int i=0;i<s.size()-1;i++){
            ans=max(ans,cnt0[i]+cnt1[i+1]);
        }
        return ans;
    }
};

放到本地IDE进行调试时,发现,在第二个for循环中,本来是倒着遍历数组,结果是变量进行了++操作。这是一个非常容易就犯的错误。

第二,所给数据是否有前导0

在有的算法题中,会在有些测试点的数据里面放置前导0,例如(后序添加题目链接),这种情况之下,需要首先将前导0去掉。

第三,关于容器的容量

今天在写n皇后问题时n皇后问题,遇到一个问题,问题涉及到,vector容器的size()函数
如下所示

#include <iostream>
#include <vector>
using namespace std;

int main()
{
    vector<int> ans;
    cout<<ans.size()-1;
    return 0;
}

运行结果为
在这里插入图片描述
定义了一个vector容器ans,并且未在里面放东西,所以ans.size()为0是正确的,但是当输出ans.size()-1时,确并未输出-1,这是因为容器的size()返回的是无符号整数,平时用来遍历还是可以的,不涉及进行加减操作,但是当用来加减操作时,要注意无符号整型与有符号整型的运算,可能结果和想象的不同,最好不要使用size()的结果值运算,如果非要运算,可以定义一个int类型的数,先将size()的值保存下来。可以避免想不到的错误。
2021/1/21补充,做力扣1544. Make The String Great又遇到这种情况了,原来有错误的代码如下

class Solution {
public:
    string makeGood(string s) {
        for(int i=0;i<s.size()-1; ){//注意点
            if(abs(s[i]-s[i+1])==32){
                s.erase(i,2);
                if(i) i--;
            }
            else i++;
        }
        return s;
    }
};

运行代码时,显示堆栈溢出,可是有的样例可以通过,而样例"abBAcC"通不过,只好弄在本地IDE上,

#include <iostream>
#include <unordered_map>
#include <string>

using namespace std;

int main()
{
    string s="abBAcC";
    for(int i=0;i<s.size()-1; ){
            if(abs(s[i]-s[i+1])==32){
                s.erase(i,2);
                if(i) i--;
            }
            else i++;
            cout<<i<<" "<<s.size()-1<<" "<<s<<endl;
    }
    cout<<s;
    return 0;
}

为了方便观察变量,每一步都将当前的i与s输出,运行结果截图
在这里插入图片描述
后面还有好多,没有截出来,原来是,当s变成“cC”时还没错,但是接下来就出错了,因为下一步时,i变为0,串s变为“”,即空串,空串的长度为0,但是在for循环的判断语句中,使用了i与s.size()-1进行比较,错误复现,STL容器的长度类型为无符号型,最高位解释为数据位。所以当int类型的i为0,与无符号类型的s.size()-1进行比较时,肯定会一直比较下去。
可以在判断语句中加入&&s.size(),即仅当串非空串时进行操作。

for(int i=0;i<s.size()-1&&s.size(); ){
}

或者直接将s.size()强制转换为int,解决很多问题。

for(int i=0;i<(int)s.size()-1; ){
}

第四,关于给的数据类型

注意题目中对于数据的描述字眼,数据是正数positive,还是正整数positive integer,如果只是说是正数positive,最好用double来存储,因为可能有的测试样例卡的是数据类型。例如PATA1070 Mooncake
一定要非常小心double类型数据的比较操作。因为其在内存中是存储的IEEE754标准,double类型的运算涉及对阶,左右规,精度只有23+1=24位。所以一些判断条件是double类型的数的时候,要非常小心。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值