leetcode200题之扫尾部分(四)

1. 整数反转

题目:https://leetcode-cn.com/problems/reverse-integer/

注意:res=res*10+pop;可能存在溢出问题。

class Solution {
public:
    int reverse(int x) {
        int res=0;
        int pop=0;
        while(x!=0){
            pop = x % 10;
            x /= 10;
            if(res > INT_MAX/10  || (res == INT_MAX/10 && pop > 7)){
                return 0;
            }
            if(res < INT_MIN/10  ||(res==INT_MIN/10 && pop<-8)){
                return 0;
            }
            res=res*10+pop;
        }
        return res;
    }
};

2. 反转字符串

题目:https://leetcode-cn.com/problems/reverse-string/

思路: 双指针法是使用两个指针,一个左指针 left,右指针 right,开始工作时 left 指向首元素,right 指向尾元素。交换两个指针指向的元素,并向中间移动,直到两个指针相遇。

class Solution {
public:
    void reverseString(vector<char>& s) {
        int left=0, right=s.size()-1;
        while(left<right){
            int tmp=s[left];
            s[left]=s[right];
            s[right]=tmp;
            left++;
            right--;
        }
    }
};

3. 回文数

题目:https://leetcode-cn.com/problems/palindrome-number/

思路:   (1) 转成字符串,并检查字符串是否为回文。但是,这需要额外的非常量空间来创建问题描述中所不允许的字符串。

           (2)反转整数,判断和原数是否相同,但是存在溢出问题。

           (3)  反转一半数字

首先,我们应该处理一些临界情况。所有负数都不可能是回文,除了 0 以外,所有个位是 0 的数字不可能是回文,因为最高位不等于 0。所以我们可以对所有大于 0 且个位是 0 的数字返回 false。

我们如何知道反转数字的位数已经达到原始数字位数的一半?

由于整个过程我们不断将原始数字除以 10,然后给反转后的数字乘上 10,所以,当原始数字小于或等于反转后的数字时,就意味着我们已经处理了一半位数的数字了。

class Solution {
public:
    bool isPalindrome(int x) {
        if(x<0 || (x%10==0 && x!=0)){
            return false;
        }
        int reversenum=0;
        while(x>reversenum){
            reversenum = reversenum*10 + x%10;
            x /= 10;
        }
        return x==reversenum || x==reversenum/10;
    }
};

4. 最长公共前缀 

题目:https://leetcode-cn.com/problems/longest-common-prefix/

思路:纵向比较

class Solution {
public:
    string longestCommonPrefix(vector<string>& strs) {
        if(strs.size()==0){
            return "";
        }
        int length=strs[0].size();  //列数
        int count=strs.size();     //行数

        for(int i=0; i<length; i++){
            char c=strs[0][i];
            for(int j=1; j<count; j++){
                if(i==strs[j].size() || strs[j][i]!=c){
                    return strs[0].substr(0,i);
                }
            }
        }
        return strs[0];
    }
};
*/
class Solution {
public:
    string longestCommonPrefix(vector<string>& strs) {
        string res = strs.empty()? "" : strs[0];
        for(auto s:strs){
            //s.find(res) != 0不是其前缀,开始减去res的最后一个字符
           while(s.find(res)!= 0)   res=res.substr(0,res.size()-1);
        }
        return res;
    }
};

5. 下一个排列

题目:https://leetcode-cn.com/problems/next-permutation/

思路:

  1. 我们希望下一个数比当前数大,这样才满足“下一个排列”的定义。因此只需要将后面的「大数」与前面的「小数」交换,就能得到一个更大的数。比如 123456,将 5 和 6 交换就能得到一个更大的数 123465。
  2. 我们还希望下一个数增加的幅度尽可能的小,这样才满足“下一个排列与当前排列紧邻“的要求。为了满足这个要求,我们需要:
  3. 尽可能靠右的低位进行交换,需要从后向前查找
  4. 将一个 尽可能小的「大数」 与前面的「小数」交换。比如 123465,下一个排列应该把 5 和 4 交换而不是把 6 和 4 交换
  5. 将「大数」换到前面后,需要将「大数」后面的所有数重置为升序升序排列就是最小的排列。以 123465 为例:首先按照上一步,交换 5 和 4,得到 123564;然后需要将 5 之后的数重置为升序,得到 123546。显然 123546 比 123564 更小,123546 就是 123465 的下一个排列
class Solution {
public:
    void nextPermutation(vector<int>& nums) {
        if(nums.empty())  return;
         int i=nums.size()-2;
         while(i>=0 && nums[i]>=nums[i+1]){
             i--;
         }

         if(i>=0){
            int j=nums.size()-1;
            while(j>=0 && nums[j]<=nums[i]){
                j--;
            }
            swap(nums,i,j);
         }
         reverse(nums,i+1);
    }
    void swap(vector<int> &nums, int i, int j){
        int tmp=nums[i];
        nums[i]=nums[j];
        nums[j]=tmp;
    }
    void reverse(vector<int> & nums, int i){
        int j=nums.size()-1;
        while(i<j){
            swap(nums,i,j);
            j--;
            i++;
        }
    }
};

 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值