剑指offer(五)

41. 和为S的两个数字

在这里插入图片描述

a+b=sum,a和b越远乘积越小

  • a+b=sum;a+n+b-n=sum;(a+n)(b-n)=ab+n(b-a)>ab
class Solution {
public:
    vector<int> FindNumbersWithSum(vector<int> array,int sum) {
        
        vector<int> ret;
        int l = 0;
        int r = array.size()-1;
        
        while(l < r)
        {
            int n = array[l] + array[r];
            if(n == sum)
            {
                ret.push_back(array[l]);
                ret.push_back(array[r]);
                return ret;
            }else if(n < sum){
                l++;
            }else
                r--;
        }
        
        return ret;
    }
};

42. 左旋转字符串

在这里插入图片描述

法一:

  • 字符拼接
class Solution {
public:
    string LeftRotateString(string str, int n) {
        
        string ret;
        if(n == 0 || str.length() == 0)
            return str;
        
        n = n%str.length();
        int len = str.length();
        ret = str.substr(n, len-n+1);
        ret += str.substr(0, n);
        
        return ret;
    }
};

法二:

  • 三次字符翻转(总转一次、前k个数转一次、后n-k个数转一次)
class Solution {
public:
    string LeftRotateString(string str, int n) {
        
        if(str.length()==0 || n==0)
            return str;
        
        int len = str.length();
        n %= str.length();
        
        reverse(str.begin(), str.end());
        
        reverse(str.begin(), str.begin()+len-n);
        reverse(str.begin()+len-n, str.end());
        
        return str;
    }
};

43. 翻转单词顺序列

在这里插入图片描述

class Solution {
public:
    string ReverseSentence(string str) {
        
        int len = str.length();
        if(len == 0)
            return str;
        
        int begin = 0;
        int index = str.find(" ", begin);		//没找到,返回 -1
        while(index != -1)
        {
            s.push(str.substr(begin, index-begin));
            
            begin = index + 1;
            index = str.find(" ", begin);
        }
        
        string ret = str.substr(begin);
        while(!s.empty())
        {
            ret += " " + s.top();
            s.pop();
        }
        
        return ret;
    }
    
private:
    stack<string> s;
};

44. 扑克牌顺子

在这里插入图片描述

class Solution {
public:
    bool IsContinuous( vector<int> numbers ) {
        
        if(numbers.size() == 0)
            return false;
        
        sort(numbers.begin(), numbers.end());
        
        int king = 0;
        int index = 0;
        while(index < numbers.size()-1)
        {
            if(numbers[index] == 0)
            {
                king++;
                index++;
                continue;
            }
                
            if(numbers[index]+1 == numbers[index+1]){
                index++;
                continue;
            }
            else if(king > 0){
                king--;
                numbers[index]++;
            }
            else 
                return false;
        }
        
        return true;
    }
};

45. 圆圈中最后剩下的数

在这里插入图片描述

约瑟夫环

class Solution {
public:
    int LastRemaining_Solution(int n, int m)
    {
        
        if(n<1 || m<1) 
            return -1;
        
        v = vector<bool>(n, false);
        int index = -1;
        int step = 0;
        int count = n;
        
        while(count > 0)
        {
            index++;        //指向已删除的下个元素
            index = (index==n)?0:index;
            
            if(v[index])
                continue;
            
            step++;
            
            if(step == m)
            {
                step = 0;
                count--;
                v[index] = true;
            }
           
        }
        
        return index;
    }
    
private:
    vector<bool> v;
};

46. 求1+2+3+…+n

在这里插入图片描述

&& 的短路性质模拟 if

class Solution {
public:
    int Sum_Solution(int n) {
        
        int ret = n;
        n>0 && (ret += Sum_Solution(n-1)) > 0;
        
        return ret;
    }
};

47. 不用加减乘除做加法

在这里插入图片描述

法一:自增、自减

class Solution {
public:
    int Add(int num1, int num2)
    {

        if(num1 == 0)
            return num2;
        else if(num1 > 0){
            while(num1-- != 0)
                num2++;
        }else{
            while(num1++ != 0)
                num2--;
        }
        
        return num2;
    }
};

法二:
相加 ===> 异或
进位 ===> 相与、左移一位

class Solution {
public:
    int Add(int num1, int num2)
    {

        while( num2 != 0 )
        {
            int sum = num1 ^ num2;                
            int carray = (num1 & num2) << 1;
            num1 = sum;
            num2 = carray;
        }
        
        return num1;
    }
};

48. 把字符串转换成整数

在这里插入图片描述

class Solution {
public:
    int StrToInt(string str) {
        
        int len = str.length();
        if(len == 0)
            return 0;
        
        long long ret = 0;
        int symbol = (str[0]=='-')?-1:1;
        for(int i=(str[0]=='-' || str[0]=='+')?1:0; i<len; i++)
        {
            if(str[i] < '0' || str[i] > '9')
                return 0;
            
            ret = ret * 10 + str[i] - '0';
        }
        
        return ret*symbol;
    }
};

49. 数组中重复的数字

在这里插入图片描述

法一:

class Solution {
public:
    // Parameters:
    //        numbers:     an array of integers
    //        length:      the length of array numbers
    //        duplication: (Output) the duplicated number in the array number
    // Return value:       true if the input is valid, and there are some duplications in the array number
    //                     otherwise false
    bool duplicate(int numbers[], int length, int* duplication) {
        
        if(length == 0 || !numbers)
            return false;
        
        v = vector<bool>(length, false);
        for(int i=0; i<length; i++)
        {
            if(v[numbers[i]])
            {
                *duplication = numbers[i];
                return true;
            }else
                v[numbers[i]] = true;
        }
        
        return false;
    }
    
private:
    vector<bool> v;
};

法二:
numbers[numbers[i] % len] += n, 若再次被访问则肯定大于n

class Solution {
public:
    // Parameters:
    //        numbers:     an array of integers
    //        length:      the length of array numbers
    //        duplication: (Output) the duplicated number in the array number
    // Return value:       true if the input is valid, and there are some duplications in the array number
    //                     otherwise false
    bool duplicate(int numbers[], int length, int* duplication) {
        
        if(length == 0 || !numbers)
            return false;
        
        for(int i=0; i<length; i++)
        {
            if(numbers[numbers[i]%length] >= length)
            {
                *duplication = numbers[i]%length;
                return true;
            }
            
            numbers[numbers[i]%length] += length;  
        }
        
        return false;
    }

};

50. 构建乘积数组

在这里插入图片描述
在这里插入图片描述

先从上到下计算下三角,在从下到上计算上三角

class Solution {
public:
    vector<int> multiply(const vector<int>& A) {
    
        vector<int> ret = vector<int>(A.size(), 1);
        for(int i=1; i<A.size(); i++)
            ret[i] = ret[i-1] * A[i-1];
        
        int tmp = 1;
        for(int i=A.size()-2; i>=0; i--)
        {
            tmp *= A[i+1];
            ret[i] *= tmp;
        }
            
        return ret;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值