LeetCode

1、两数之和:
给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。
你可以假设每种输入只会对应一个答案。但是,你不能重复利用这个数组中同样的元素。

示例:
给定 nums = [2, 7, 11, 15], target = 9
因为 nums[0] + nums[1] = 2 + 7 = 9
所以返回 [0, 1]
方法一:暴力
方法二:

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        vector<int> res;
        if(nums.empty()){
            return res;
        }
        int n=nums.size();
        unordered_map<int,int> maps;
        for(int i=0;i<n;i++){
            maps[nums[i]]=i;
        }
        for(int i=0;i<n;i++){
            auto item=maps.find(target-nums[i]);
            if(item!=maps.end() && item->second!=i){
                res.push_back(i);
                res.push_back(item->second);
                break;
            }
        }
        return res;
    }
};

方法三:

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        vector<int> res;
        if(nums.empty()){
            return res;
        }
        int n=nums.size();
        unordered_map<int,int> maps;
        
        for(int i=0;i<n;i++){
            auto item=maps.find(target-nums[i]);
            if(item!=maps.end() && item->second!=i){
                res.push_back(item->second);
                res.push_back(i);
                break;
            }
            maps[nums[i]]=i;
        }
        return res;
    }
};

2、两数相加
给出两个 非空 的链表用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字。

如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。

您可以假设除了数字 0 之外,这两个数都不会以 0 开头。

示例:

输入:(2 -> 4 -> 3) + (5 -> 6 -> 4)
输出:7 -> 0 -> 8
原因:342 + 465 = 807

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
        if(l1==NULL && l2==NULL) return NULL;
        if(l1==NULL) return l2;
        if(l2==NULL) return l1;
        ListNode * newHead=new ListNode(-1);
        ListNode * p=newHead;
        int add=0;
        while(l1!=NULL && l2!=NULL){
            int sum=l1->val+l2->val+add;
            add=sum/10;
            ListNode * temp=new ListNode(sum%10);
            p->next=temp;
            p=p->next;
            l1=l1->next;
            l2=l2->next;
        }
        while(l1!=NULL){
            int sum=l1->val+add;
            add=sum/10;
            ListNode * temp=new ListNode(sum%10);
            p->next=temp;
            p=p->next;
            l1=l1->next;
        }
        while(l2!=NULL){
            int sum=l2->val+add;
            add=sum/10;
            ListNode * temp=new ListNode(sum%10);
            p->next=temp;
            p=p->next;
            l2=l2->next;
        }
        //重点别忘了最后的进位
        if(add==0)
            return newHead->next;
        ListNode * temp=new ListNode(add);
        p->next=temp;
        return newHead->next;
    }
};

缩减代码:

class Solution {
public:
    ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
        if(l1==NULL && l2==NULL) return NULL;
        if(l1==NULL) return l2;
        if(l2==NULL) return l1;
        ListNode * newHead=new ListNode(-1);
        ListNode * p=newHead;
        int add=0;
        while(l1!=NULL || l2!=NULL){
            int sum=l1!=NULL?l1->val:0;
            sum+=l2!=NULL?l2->val:0;
            sum+=add;
            add=sum/10;
            ListNode * temp=new ListNode(sum%10);
            p->next=temp;
            p=p->next;
            if(l1!=NULL)  l1=l1->next;
            if(l2!=NULL)  l2=l2->next;
        }
        if(add>0)
            p->next=new ListNode(add);
        return newHead->next;
    }
};

3. 无重复字符的最长子串

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        if(s.empty()){
            return 0;
        }
        int n=s.size();
        if(n==1){
            return 1;
        }
        vector<int> count(256,0);
        int left=0,right=0;
        int maxLen=-1;
        while(right<n){
            int index=s[right];
            while(count[index]==1){
                count[s[left]]--;
                left++;
            }
            count[index]++;
            right++;
            maxLen=max(maxLen,right-left);
        }
        return maxLen;
    }
};

方法二:

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        if(s.empty()){
            return 0;
        }
        int n=s.size(),ans=0;
        vector<int> index(128);//current index of char
        for(int j=0,i=0;j<n;j++){
            i=max(index[s[j]],i);
            ans=max(ans,j-i+1);
            index[s[j]]=j+1;
        }
        return ans;
    }
};

5. 最长回文子串

给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。

示例 1:

输入: “babad”
输出: “bab”
注意: “aba” 也是一个有效答案。
示例 2:

输入: “cbbd”
输出: “bb”
方法一:暴力
方法二:

class Solution {
public:
    string longestPalindrome(string s) {
        if(s.empty()){
            return "";
        }
        int n=s.size();
        int start=0,maxLen=0;
        for(int i=0;i<n;i++){
            int len1=patter(s,i,i);
            int len2=patter(s,i,i+1);
            if(len1>maxLen && len1>len2){
                start=i-len1/2;
                maxLen=len1;
            }
            if(len2>maxLen && len2>len1){
                start=i-len2/2+1;
                maxLen=len2;
            }
        }
        return s.substr(start,maxLen);
    }
    int patter(string s,int i,int j){
        while(i>=0 && j<s.size() && s[i]==s[j]){
            i--;
            j++;
        }
        return j-i-1;
    }
};

方法三:动态规划

class Solution {
public:
    string longestPalindrome(string s) {
        if(s.empty()){
            return "";
        }
        int n=s.size();
        vector<vector<bool> > dp(n,vector<bool>(n,false));
        int start=0,maxLen=0;
        for(int i=0;i<n;i++){
            for(int j=i;j>=0;j--){
                dp[j][i]=(s[i]==s[j] && (i-j<2 || dp[j+1][i-1]));
                if(dp[j][i] && i-j+1>maxLen){
                    start=j;
                    maxLen=i-j+1;
                }
            }
        }
        return s.substr(start,maxLen);
    }
    
};

6. Z 字形变换
将一个给定字符串根据给定的行数,以从上往下、从左到右进行 Z 字形排列。

比如输入字符串为 “LEETCODEISHIRING” 行数为 3 时,排列如下:

L C I R
E T O E S I I G
E D H N
之后,你的输出需要从左往右逐行读取,产生出一个新的字符串,比如:“LCIRETOESIIGEDHN”。

请你实现这个将字符串进行指定行数变换的函数:

string convert(string s, int numRows);
示例 1:

输入: s = “LEETCODEISHIRING”, numRows = 3
输出: “LCIRETOESIIGEDHN”

class Solution {
public:
    string convert(string s, int numRows) {
        if(s.empty() || numRows==1){
            return s;
        }
        
        int len=numRows+numRows-2;
        vector<string> res(numRows,"");
        for(int i=0;i<s.size();i++){
            int yu=i%len;
            if(yu<numRows){
                res[yu]+=s[i];
            }else{
                int index=numRows-(yu-numRows+2);
                res[index]+=s[i];
            }
        }
        string result;
        for(int i=0;i<res.size();i++){
            result+=res[i];
        }
        return result;
    }
};

7. 整数反转
给出一个 32 位的有符号整数,你需要将这个整数中每位上的数字进行反转。

示例 1:

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

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

输入: 120
输出: 21
注意:

假设我们的环境只能存储得下 32 位的有符号整数,则其数值范围为 [−231, 231 − 1]。请根据这个假设,如果反转后整数溢出那么就返回 0。

class Solution {
public:
    int reverse(int x) {
        
        long res=0;
        while(x!=0){
            res=res*10+x%10;
            x=x/10;
        }
        long left=pow(-2,31),right=pow(2,31)-1;
        if(res<INT_MIN || res>INT_MAX){
            return 0;
        }
        return res;
    }
};

9. 回文数

class Solution {
public:
    bool isPalindrome(int x) {
   		// 特殊情况:
        // 如上所述,当 x < 0 时,x 不是回文数。
        // 同样地,如果数字的最后一位是 0,为了使该数字为回文,
        // 则其第一位数字也应该是 0
        // 只有 0 满足这一属性
        if(x < 0 || (x % 10 == 0 && x != 0)) {
            return false;
        }
        long long res=0;
        int y=x;
        while(x>res){
            res=res*10+x%10;
            x=x/10;
        }
        // 当数字长度为奇数时,我们可以通过 revertedNumber/10 去除处于中位的数字。
        // 例如,当输入为 12321 时,在 while 循环的末尾我们可以得到 x = 12,
        //revertedNumber = 123,
        // 由于处于中位的数字不影响回文(它总是与自己相等),所以我们可以简单地将其去除。
        return x==res || x==res/10;
    }
};

11. 盛最多水的容器
在这里插入图片描述

class Solution {
public:
    int maxArea(vector<int>& height) {
        if(height.empty()){
            return 0;
        }
        int maxArea=-1;
        int left=0,right=height.size()-1;
        while(left<right){
            maxArea=max(min(height[left],height[right])*(right-left),maxArea);
            if(height[right]>height[left]){
                left++;
            }else{
                right--;
            }            
        }
        return maxArea;
    }
};

12. 整数转罗马数字

在这里插入图片描述

class Solution {
public:
    string intToRoman(int num) {
        int values[]={1000,900,500,400,100,90,50,40,10,9,5,4,1};
        string reps[]={"M","CM","D","CD","C","XC","L","XL","X","IX","V","IV","I"};
        string res;
        for(int i=0;i<13;i++){
            while(num>=values[i]){
                num-=values[i];
                res+=reps[i];
            }
        }
        return res;
    }
};

15. 三数之和
给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组。

注意:答案中不可以包含重复的三元组。

例如, 给定数组 nums = [-1, 0, 1, 2, -1, -4],

满足要求的三元组集合为:
[
[-1, 0, 1],
[-1, -1, 2]
]

class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        vector<vector<int> > res;
        if(nums.empty() || nums.size()<3){
            return res;
        }
        sort(nums.begin(),nums.end());
        for(int i=0;i<nums.size()-2;i++){
            if(nums[i]>0){
                break;
            }
            if(i>0 && nums[i]==nums[i-1]) continue;
            int left=i+1,right=(int)nums.size()-1;
            while(left<right){
                if(nums[left]+nums[right]==0-nums[i]){
                    res.push_back({nums[i],nums[left],nums[right]});
                    while(left<right && nums[left] == nums[left+1]) left++;
                    while(left<right && nums[right]==nums[right-1]) right--;
                    left++;
                    right--;
                }else if(nums[left]+nums[right]<0-nums[i]){
                    left++;
                }else{
                    right--;
                }
            }
        }
        return res;
    }
};

18. 四数之和
在这里插入图片描述

class Solution {
public:
    vector<vector<int>> fourSum(vector<int>& nums, int target) {
        vector<vector<int> > res;
        if(nums.empty() || nums.size()<4){
            return res;
        }
        sort(nums.begin(),nums.end());
        for(int i=0;i<nums.size()-3;i++){
            if(i>0 && nums[i]==nums[i-1]) continue;
            for(int j=i+1;j<nums.size()-2;j++){
                if(j>i+1 && nums[j]==nums[j-1]) continue;
                int left=j+1,right=nums.size()-1;
                while(left<right){
                    int sum=nums[i]+nums[j]+nums[left]+nums[right];
                    if(sum==target){
                        res.push_back({nums[i],nums[j],nums[left],nums[right]});
                        while(left<right && nums[left]==nums[left+1]) left++;
                        while(left<right && nums[right]==nums[right-1]) right--;
                        left++;
                        right--;
                    }else if(sum<target){
                        left++;
                    }else{
                        right--;
                    }
                }
            }
        }
        return res;
    }
};

19. 删除链表的倒数第N个节点
注意边界问题
在这里插入图片描述

class Solution {
public:
    ListNode* removeNthFromEnd(ListNode* head, int n) {
        if(head==NULL){
            return head;
        }
        ListNode * fast=head,* slow=head;
        int k=1;
        while(fast!=NULL){
            if(k<=n+1){
                fast=fast->next;
                k++;
            }else{
                slow=slow->next;
                fast=fast->next;
            }
        }
        if(k<=n+1)
            return head->next;
        slow->next=slow->next->next;
        return head;
    }
};

22. 括号生成
在这里插入图片描述

class Solution {
public:
    vector<string> generateParenthesis(int n) {
        vector<string> res;
        help(res,"",0,0,n);
        return res;
    }
    void help(vector<string> &res,string cur,int open,int close,int max){
        if(cur.size()==max*2){
            res.push_back(cur);
            return ;
        }
        if(open<max)
            help(res,cur+"(",open+1,close,max);
        if(close<open)
            help(res,cur+")",open,close+1,max);
    }
};
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值