LeetCode前两百刷题(1~20)

leetcode

lc1 & lc15& lc 16 & lc 18

多数之和问题

https://www.jianshu.com/p/0b91c4b3a135

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

https://www.jianshu.com/p/a69766441eb8

4.找两个数组的中位数

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

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

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

不需要合并两个有序数组,只要找到中位数的位置即可。由于两个数组的长度已知,因此中位数对应的两个数组的下标之和也是已知的。维护两个指针,初始时分别指向两个数组的下标 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 resarr(5);
        string resarr[numRows];//用vector初始化貌似有问题,vector合适的初始化方式
        fill(resarr,resarr+numRows,"");
        // fill(resarr.begin(),resarr.end(),"");//vector这样不可,但是数组可。

        for(int i=0;i

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
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 || result0){
            
        // }
        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='0'&&str[index]<='9')&&str[index]!='-'&&str[index]!='+')//非正常字符
            return 0;

        int abss=1;//判断符合的正负
        long count=0;
        int nowindex=index;
        while(index='0'&&str[index]<='9'))
                break;
            count=count*10;
            count+=(str[index]-'0');
           // cout<INT_MAX)//注意截断,考虑绝对值要注意最大最小值不同
                return INT_MAX;
            if((abss==-1) &&-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;i0&&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(i0&&p[index2-1]=='*'&&i>1&&p[index2]==s[i-1]){
                index2+=1;
                continue;
            }
            //没有匹配成功,后面有*也无所谓
            if(index2s.length())
                    return false;
                return nowstr==s.substr(s.length()-nowstr.length());
            }
            
            if(p[p.length()-1]!='*')//p还有
            return false;
            if(p[index2]=='*'){
                while(index2

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 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

lc14 最长公共子缀

横向比较,纵向比较

https://www.jianshu.com/p/41a662d6127e

lc17 电话号码-dfs

https://www.jianshu.com/p/1a6b37b15f42

lc20 括号

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

class Solution {
public:
    bool isValid(string s) {
        stack tmp;
        for(int i=0;i

你可能感兴趣的:(LeetCode前两百刷题(1~20))