leetcode 两数相加/最长回文子串/字符串转换整数(atoi)/盛最多水的容器/三数之和/最接近的三数之和

两数相加

题目链接:https://leetcode-cn.com/problems/add-two-numbers/

/**
 * 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) {
        int num=(l1->val+l2->val)%10;
        int div=(l1->val+l2->val)/10;
        ListNode *head=new ListNode(num);
        ListNode *l3=head;
        l1=l1->next;
        l2=l2->next;
        
        while(l1&&l2)
        {
            num=(div+l1->val+l2->val)%10;
            div=(div+l1->val+l2->val)/10;
            l3->next=new ListNode(num);
            l3=l3->next;
            l1=l1->next;
            l2=l2->next;
        }
        
        //如果l1还没有遍历完
        while(l1)
        {
            num=(div+l1->val)%10;
            div=(div+l1->val)/10;
            l3->next=new ListNode(num);
            l3=l3->next;
            l1=l1->next;
        }
        
        //如果l2还没有遍历完
        while(l2)
        {
            num=(div+l2->val)%10;
            div=(div+l2->val)/10;
            l3->next=new ListNode(num);
            l3=l3->next; 
            l2=l2->next;
        }
        
        if(div!=0)
        {
            l3->next=new ListNode(div);
            l3=l3->next;
        }
        return head;
    }
};

有点像merge2个有序链表的操作,注意进位即可

最长回文子串

题目链接:https://leetcode-cn.com/problems/longest-palindromic-substring/

博客指路

字符串转换整数(atoi)

题目链接:https://leetcode-cn.com/problems/string-to-integer-atoi/

class Solution {
public:
    int deal_with_cal(string &str,int index)
    {
        //首先判断,刚开始的加减符号是不是最后一个字符或者加减符号后是否不是数字
        //如果满足任意一种情况都直接返回0
        if(index+1>=str.size()||(str[index+1]<'0'||str[index+1]>'9'))
            return 0;
        
        //记录标点符号
        bool minus=false;
        if(str[index]=='-')
            minus=true;
        
        long long num=0;
        
        for(int i=index+1;i<str.size();i++)
        {
            if(str[i]>='0'&&str[i]<='9')
            {
                num=num*10+(str[i]-'0');
                //如果超出负数范围
                if(minus&&(num-1>INT_MAX))
                    return INT_MIN;
                else if(!minus&&(num>INT_MAX))
                    return INT_MAX;
            }
            else 
                break;
        }
        
        if(minus)
            return num*(-1);
        else
            return num;        
    }
    
    int deal_with_num(string &str,int index)
    {
        long long num=0;
        for(int i=index;i<str.size();i++)
        {
            if(str[i]>='0'&&str[i]<='9')
            {
                num=num*10+(str[i]-'0');
                //如果超出范围
                if(num>INT_MAX)
                    return INT_MAX;
            }
            else 
                break;
        }        
        return num;         
    }
    
    
    int myAtoi(string str) {
        if(str.size()==0)
            return 0;
        
        for(int i=0;i<str.size();i++)
        {
            if(str[i]==' ')
                continue;
            
            //碰到加减
            else if(str[i]=='+'||str[i]=='-')
            {
                return deal_with_cal(str,i);
            }
            
            //碰到数字
            else if(str[i]>='0'&&str[i]<='9')
            {
                return deal_with_num(str,i);
            }
            
            //不是加减或数字
            else
            {
                return 0;
            }
        }
        return 0;
        
    }
};

注意有一句代码:num-1>INT_MAX这句并不可以写成num>1+INT_MAX,因为1+INT_MAX会变为INT_MIN

盛最多水的容器

题目链接:https://leetcode-cn.com/problems/container-with-most-water/

class Solution {
public:
    int maxArea(vector<int>& height) {
        if(height.size()==2)
            return height[0]>height[1]?height[1]:height[0];
        int maxw=0;
        int i=0,j=height.size()-1;
        while(i<j)
        {
            int temw=(j-i)*(height[j]>height[i]?height[i]:height[j]);
            if(temw>maxw)
                maxw=temw;
            if(height[j]>height[i])
                i++;
            else
                j--;
        }
        return maxw;
    }
};

从2头往中间挤,当间距在缩小时,要想获得最大容量必须使最低木板变高,才有可能得到最大值。

三数之和

题目链接:https://leetcode-cn.com/problems/3sum/

class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        vector<vector<int>> vt;
        if(nums.size()<3)
            return vt;
        
        sort(nums.begin(),nums.end());
        map<int,int> mp;
        
        for(int i=0;i<nums.size()-2;i++)
        {
            //如果本身已经大于0 ,直接返回
            if(nums[i]>0)
                return vt;
            //如果之前处理过这个数,不再处理
            if(mp[nums[i]])
                continue;
            mp[nums[i]]++;
            
            int lptr=i+1;
            int rptr=nums.size()-1;
            
            while(lptr<rptr)
            {
                if(nums[i]+nums[lptr]+nums[rptr]==0)
                {
                    vt.push_back(vector<int> {nums[i],nums[lptr],nums[rptr]});
                    do
                    {
                        lptr++;
                    }while(nums[lptr-1]==nums[lptr]&&lptr<rptr);
                    
                    do
                    {
                        rptr--;
                    }while(nums[rptr+1]==nums[rptr]&&lptr<rptr);
                }
                
                else if(nums[i]+nums[lptr]+nums[rptr]>0)
                {
                    do
                    {
                        rptr--;
                    }while(nums[rptr+1]==nums[rptr]&&lptr<rptr);
                }
                
                else
                {
                    do
                    {
                        lptr++;
                    }while(nums[lptr-1]==nums[lptr]&&lptr<rptr);
                }
            }
        }
        return vt;    
    }
};

先排序,然后从左到右依次固定住一个数作为第一个数,之后选另外2个数(用左右夹击的方法),如果该数满足要注意之后的去重。

最接近的三数之和

题目链接:https://leetcode-cn.com/problems/3sum-closest/

class Solution {
public:
    int threeSumClosest(vector<int>& nums, int target) {
        if(nums.size()==3)
            return nums[0]+nums[1]+nums[2];
        sort(nums.begin(),nums.end());
        
        //为正
        if(target&&nums[nums.size()-1]<=0)
            return nums[nums.size()-1]+nums[nums.size()-2]+nums[nums.size()-3];
        
        if(!target&&nums[0]>=0)
            return nums[0]+nums[1]+nums[2];
        
        int res;
        int abs_minus_min=INT_MAX;
        int j=nums.size()-1;
        
        for(int i=0;i<j;i++)
        {
            int lptr=i+1;
            int rptr=j;
            while(lptr<rptr)
            {
                int temp_minus=nums[i]+nums[lptr]+nums[rptr]-target;
                if(abs(temp_minus)<abs_minus_min)
                {
                    abs_minus_min=abs(temp_minus);
                    res=nums[i]+nums[lptr]+nums[rptr];
                }
                
                //如果差值为正,右边左移
                if(temp_minus>0)
                    rptr--;
                else if(temp_minus<0)
                    lptr++;
                else
                    return res;
            }
        } 
        return res;
    }
};

差不多的套路,只是不用去重而已,因为最后答案只有一个。

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值