LeetCode前两百刷题(1~20)

leetcode

lc1 & lc15& lc 16 & lc 18

多数之和问题

//www.greatytc.com/p/0b91c4b3a135

lc 3 & lc11 &lc 42 &lc19 & lc26-双指针

//www.greatytc.com/p/a69766441eb8

4.找两个数组的中位数

有一种解法是vector直接放在一起,然后排序得到中位数。

我过去的解法:用归并排序做的。归并排序也是用一个新的vector<int>放结果。

还有一种方法,双指针,↓,双指针一个一直移动。

不需要合并两个有序数组,只要找到中位数的位置即可。由于两个数组的长度已知,因此中位数对应的两个数组的下标之和也是已知的。维护两个指针,初始时分别指向两个数组的下标 00 的位置,每次将指向较小值的指针后移一位(如果一个指针已经到达数组末尾,则只需要移动另一个数组的指针),直到到达中位数的位置。

作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/median-of-two-sorted-arrays/solution/xun-zhao-liang-ge-you-xu-shu-zu-de-zhong-wei-s-114/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

第一种思路的时间复杂度是 O(m+n),空间复杂度是 O(m+n)。第二种思路虽然可以将空间复杂度降到 O(1),但是时间复杂度仍是 O(m+n)。

也可以用二分查找方法,

(二分查找方法,我试了一下,然后被边界和情况绕晕了。)(见LeetCode题解)

二分查找的时间复杂度是O(log(m+n))

6.z字形变换

计算格子差(模拟)

class Solution {
public:
    string convert(string s, int numRows) {
        if(numRows==0)
            return "";
        if(numRows==1||s.length()==0)
            return s;
        
        if(numRows==2){
            string s1="";
            string s2="";
            for(int i=0;i<s.length();i++){
                // cout<<s1<<" "<<s2<<endl;
                if(i%2==0){
                    s1+=s[i];
                }else{
                    s2+=s[i];
                }
                
            }
            return s1+s2;
        }
        string res = "";
        // vector<string> resarr(5);
        string resarr[numRows];//用vector初始化貌似有问题,vector合适的初始化方式
        fill(resarr,resarr+numRows,"");
        // fill(resarr.begin(),resarr.end(),"");//vector这样不可,但是数组可。

        for(int i=0;i<numRows;i++){
            int index = i;
            int op=0;
            int lastindex=-1;
            while(index<s.length()){
                if(lastindex!=index){
                    resarr[i]+=s[index];
                    lastindex=index;
                }
                if(op==0){
                    index += 2*numRows-2*i-2;
                    op=1;
                }else if(op==1){
                    index += 2*i;
                    op=0;
                }
            }
        }
        for(int i=0;i<numRows;i++){
            res+=resarr[i];
            // cout<<res<<endl;
        }
        
        return res;

    }
};

7.整数反转

给你一个 32 位的有符号整数 x ,返回将 x 中的数字部分反转后的结果。

如果反转后整数超过 32 位的有符号整数的范围 [−231,  231 − 1] ,就返回 0。

假设环境不允许存储 64 位整数(有符号或无符号)。
 

示例 1:

输入:x = 123
输出:321
示例 2:

输入:x = -123
输出:-321
示例 3:

输入:x = 120
输出:21
示例 4:

输入:x = 0
输出:0
 

提示:

-231 <= x <= 231 - 1

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/reverse-integer
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

对于大数的运用。用了取余和连乘。

#include<cmath>
class Solution {
public:
    int reverse(int x) {
        long a=INT_MAX;
        long b=INT_MIN;
        long long result=0;
        long long y=(long long)abs((long)x);
        long z=y;
        while(y>0){
            int x=y%10;
            result=(result*10+x);
            y=y/10;
        }
        if(result>a || result<b){
            return 0;
        }
        // int a[wei];
        // int index=0;
        // while(z>0){
            
        // }
        if(x>0)
        return result;
        else
        return -result;
        

        
    }
};

8.字符串转换整数(atoi)

请你来实现一个 myAtoi(string s) 函数,使其能将字符串转换成一个 32 位有符号整数(类似 C/C++ 中的 atoi 函数)。

函数 myAtoi(string s) 的算法如下:

读入字符串并丢弃无用的前导空格
检查下一个字符(假设还未到字符末尾)为正还是负号,读取该字符(如果有)。 确定最终结果是负数还是正数。 如果两者都不存在,则假定结果为正。
读入下一个字符,直到到达下一个非数字字符或到达输入的结尾。字符串的其余部分将被忽略。
将前面步骤读入的这些数字转换为整数(即,"123" -> 123, "0032" -> 32)。如果没有读入数字,则整数为 0 。必要时更改符号(从步骤 2 开始)。
如果整数数超过 32 位有符号整数范围 [−231,  231 − 1] ,需要截断这个整数,使其保持在这个范围内。具体来说,小于 −231 的整数应该被固定为 −231 ,大于 231 − 1 的整数应该被固定为 231 − 1 。
返回整数作为最终结果。
注意:

本题中的空白字符只包括空格字符 ' ' 。
除前导空格或数字后的其余字符串外,请勿忽略 任何其他字符。
 

示例 1:

输入:s = "42"
输出:42
解释:加粗的字符串为已经读入的字符,插入符号是当前读取的字符。
第 1 步:"42"(当前没有读入字符,因为没有前导空格)
         ^
第 2 步:"42"(当前没有读入字符,因为这里不存在 '-' 或者 '+')
         ^
第 3 步:"42"(读入 "42")
           ^
解析得到整数 42 。
由于 "42" 在范围 [-231, 231 - 1] 内,最终结果为 42 。
示例 2:

输入:s = "   -42"
输出:-42
解释:
第 1 步:"   -42"(读入前导空格,但忽视掉)
            ^
第 2 步:"   -42"(读入 '-' 字符,所以结果应该是负数)
             ^
第 3 步:"   -42"(读入 "42")
               ^
解析得到整数 -42 。
由于 "-42" 在范围 [-231, 231 - 1] 内,最终结果为 -42 。
示例 3:

输入:s = "4193 with words"
输出:4193
解释:
第 1 步:"4193 with words"(当前没有读入字符,因为没有前导空格)
         ^
第 2 步:"4193 with words"(当前没有读入字符,因为这里不存在 '-' 或者 '+')
         ^
第 3 步:"4193 with words"(读入 "4193";由于下一个字符不是一个数字,所以读入停止)
             ^
解析得到整数 4193 。
由于 "4193" 在范围 [-231, 231 - 1] 内,最终结果为 4193 。
示例 4:

输入:s = "words and 987"
输出:0
解释:
第 1 步:"words and 987"(当前没有读入字符,因为没有前导空格)
         ^
第 2 步:"words and 987"(当前没有读入字符,因为这里不存在 '-' 或者 '+')
         ^
第 3 步:"words and 987"(由于当前字符 'w' 不是一个数字,所以读入停止)
         ^
解析得到整数 0 ,因为没有读入任何数字。
由于 0 在范围 [-231, 231 - 1] 内,最终结果为 0 。
示例 5:

输入:s = "-91283472332"
输出:-2147483648
解释:
第 1 步:"-91283472332"(当前没有读入字符,因为没有前导空格)
         ^
第 2 步:"-91283472332"(读入 '-' 字符,所以结果应该是负数)
          ^
第 3 步:"-91283472332"(读入 "91283472332")
                     ^
解析得到整数 -91283472332 。
由于 -91283472332 小于范围 [-231, 231 - 1] 的下界,最终结果被截断为 -231 = -2147483648 。
 

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/string-to-integer-atoi
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路:

完全按照要求写下来,可能需要注意很多细节。

这里需要使用long。

C++里最大最小 INT_MIN,INT_MAX

class Solution {
public:
    int myAtoi(string str) {
        int index=0;
        while(str[index]==' '&&index<str.length()){//去掉空格
            index++;
        }
        if(index==str.length())
             return 0;
        if (!(str[index]>='0'&&str[index]<='9')&&str[index]!='-'&&str[index]!='+')//非正常字符
            return 0;

        int abss=1;//判断符合的正负
        long count=0;
        int nowindex=index;
        while(index<str.length()){
            //cout<<str[nowindex]<<endl;
            if(nowindex!=-1&&str[nowindex]=='-'){//判断符号
                abss=-1;
                index++;
                nowindex=-1;
                continue;
            }
            if(nowindex!=-1&&str[nowindex]=='+'){
                abss=1;
                index++;
                nowindex=-1;
                continue;
            }
            if(!(str[index]>='0'&&str[index]<='9'))
                break;
            count=count*10;
            count+=(str[index]-'0');
           // cout<<count<<endl;
            index++;

            if(abss==1&&count>INT_MAX)//注意截断,考虑绝对值要注意最大最小值不同
                return INT_MAX;
            if((abss==-1) &&-count<INT_MIN){
               // cout<<count<<endl;
                return INT_MIN;}
            


        }
        if(abss==1)
            return count;
        else
            return -count;
        
    }
};

9.回文数

判断数字是否是回文数字。

1.121 回文数字 1200001不是回文数字,-121不是,因为有负号

这道题转为字符串很好做。

另一个思路是把数字倒过来,然后看看是不是相等。

class Solution {
public:
    bool isPalindrome(int x) {
        if(x<0){
            return false;
        }
        //会做字符串版的
        //int 转字符串
        //但是另一种思路是:数字反转后 数字和原数大小相同
        // res=res*10+x%10 x/=10 比较res==temp(原数字)
        // string xx=to_string(x);
        // for(int i=0;i<xx.length()/2;i++){
        //     if(xx[i]!=xx[xx.length()-1-i])
        //         return false;
        // }

        int tmp=x;
        int res=0;
        while(x>0&&res<=(INT_MAX-x%10)/10){//要考虑溢出
            res=res*10+x%10;
            x=x/10;
        }
        return res==tmp;
        
    }
};

10.【动态规划-没有看完】正则匹配

开始想用分情况讨论讨论出来,后来发现居然是动态规划。

分情况没有通过↓,只能过280个例子

class Solution {
public:
    bool isMatch(string s, string p) {
        int i=0;
        int index2=0;
        while(i<s.length()&&index2<p.length()){
            // cout<<i<<'\t'<<index2<<endl;
            if(s[i]==p[index2]||p[index2]=='.'){//匹配成功
                i++;
                index2+=1;
                continue;
            }
            if(p[index2]=='*'){
                if(s[i]==p[index2-1]||p[index2-1]=='.')//前面匹配成功,就可以继续go on
                    i++;
                else{
                    index2+=1;
                }
                continue;
            }

//             
            //这次没有匹配成功,看是不是前面有*,有*无所谓
            if(index2-1>0&&p[index2-1]=='*'&&i>1&&p[index2]==s[i-1]){
                index2+=1;
                continue;
            }
            //没有匹配成功,后面有*也无所谓
            if(index2<p.length()-1&&p[index2+1]=='*'){
                index2+=2;
                continue;
            }
            return false;
        }
        // cout<<i<<index2<<endl;
        if(i<s.length())
            return false;

        if(index2<p.length()){//看看后面有没有*
            string nowstr = p.substr(index2+1);
            if(nowstr.find('*')==nowstr.npos){
            // cout<<s.substr(s.length()-nowstr.length())<<endl;
                if(nowstr.length()>s.length())
                    return false;
                return nowstr==s.substr(s.length()-nowstr.length());
            }
            
            if(p[p.length()-1]!='*')//p还有
            return false;
            if(p[index2]=='*'){
                while(index2<p.length()){
                    if(p[index2]!='*')
                        return false;
                    index2+=2;
                }
            }
            if(index2+1<p.length()&&p[index2+1]=='*'){
                index2=index2+1;
                while(index2<p.length()){
                    if(p[index2]!='*')
                        return false;
                    index2+=2;
                }
            }
        }
        return true;
    }
};

lc12 整数转罗马数字

1.特殊情况特殊考虑

2.除法和取余,从大到小,逐个计算。

class Solution {
public:
    string intToRoman(int num) {
        //考虑时间复杂度
        // int a[]={1,5,10,50,100,500,1000};
        // string s[]={"I","V","X","L","C","D","M"};
        int a[]={1,4,5,9,10,40,50,90,100,400,500,900,1000};
        string s[]={"I","IV","V","IX","X","XL","L","XC","C","CD","D","CM","M"};
        if(num==4)
            return "IV";
        if(num==9)
            return "IX";
        if(num==40)
            return "XL";
        if(num==90)
            return "XC";
        if(num==400)
            return "CD";
        if(num==900)
            return "CM";
        int i=12;
        for(;i>=0;i--){
            if(num>=a[i])
                break;
        }
        string res="";
        bool ex=true;
        //利用数组,实现一一对应(其实这里可以用map)
        //map是自带排序的
        while(ex){
            int tmp=num/a[i];//得到多少个
            int yu=num%a[i];//得到剩下的数字
            for(int j=tmp;j>0;j--){
                res+=s[i];
            }
            num=yu;
            i--;
            if(yu==0){//没有剩下的数字了
                ex=false;
            }
        }
        return res;
    }
};

lc13 罗马数字转整数

1.罗马数字有一些特殊的,需要提前写出来。

2.如果存在特殊的,则优先计算特殊的,否则就正常加数字。

class Solution {
public:
    int romanToInt(string s) {
        map<string,int> c2num={{"I",1},{"V",5},{"X",10},{"L",50},{"C",100},{"D",500},{"M",1000},{"IV",4},{"IX",9},{"XL",40},{"XL",40},{"XC",90},{"CD",400},{"CM",900}};
        if(c2num.find(s)!=c2num.end()){
            return c2num[s];
        }
        int res=0;
        for(int i=0;i<s.length();i++){
            if(i+1<s.length()&&c2num.find(s.substr(i,2))!=c2num.end()){
                res+=c2num[s.substr(i,2)];
                i=i+1;
            }else{
                string xx = s.substr(i,1);
                res+=c2num[xx];

            }

        }
    return res;
    }
};

lc14 最长公共子缀

横向比较,纵向比较

//www.greatytc.com/p/41a662d6127e

lc17 电话号码-dfs

//www.greatytc.com/p/1a6b37b15f42

lc20 括号

直接用栈,如果有就消掉一对括号。

class Solution {
public:
    bool isValid(string s) {
        stack<char> tmp;
        for(int i=0;i<s.length();i++){
            if(s[i]=='('||s[i]=='['||s[i]=='{'){
                tmp.push(s[i]);
            }else{
                if(tmp.empty())
                    return false;
                if(s[i]==')'){
                    if(tmp.top()!='('){
                        return false;
                    }
                    
                }else if(s[i]==']'&& tmp.top()!='[')
                    return false;
                else if(s[i]=='}'&& tmp.top()!='{')
                    return false;
                tmp.pop();
            }
        }
        if(!tmp.empty())
            return false;
        return true;

    }
};
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,743评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,296评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,285评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,485评论 1 283
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,581评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,821评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,960评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,719评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,186评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,516评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,650评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,329评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,936评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,757评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,991评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,370评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,527评论 2 349

推荐阅读更多精彩内容