1.和为s的数字
(1)合为s的两个数字:输入一个递增数组和一个数字s,在数组中任意找两个数,使得他们的和正好是s。
思路:双指针,因为是排序数组,定义两个指针,一个在头一个在尾,如果二者相加小于s,那么就头++,大于s的话,尾++,等于s,返回这两个数。

class Solution {
public:
    vector<int> FindNumbersWithSum(vector<int> array,int sum) {
        int len=array.size();
        vector<int> res;
        if(len<=1) return res;
        int left=0;
        int right=len-1;//双指针
        while(left<right)
        {
            if(array[left]+array[right]==sum)
            {
                res.push_back(array[left]);
                res.push_back(array[right]);
                return res;
            }
            else if(array[left]+array[right]<sum)
            {
                left++;//小于,头右移
            }
            else
            {
                right--;//大于,尾左移
            }
        }
        return res;
    }
};

(2)和为s的连续正数序列:输入一个正数s,打印出所有和为s的连续正数序列(至少含两个数)。如12345,456,78都等于15.
思路:仍是双指针的思想,定义一个small指针,一个big指针,如果二者连续序列的和大于s,那么就small++(使序列变短),如果小于s的话,就big++(使序列变长)。因为序列至少要有两个数字,因此一直增加small到(1+s)/2为止。

class Solution {
public:
    vector<vector<int> > FindContinuousSequence(int sum) {
        vector<vector<int>> res;
        vector<int> cur;
        if(sum<3) return res;
        int small=1,big=2;
        int num=small+big;//记录当前序列值
        while(small<(sum+1)/2)//因为序列至少要两个数字
        {
            if(num==sum)
            {
                for(int i=small;i<=big;i++)
                {
                    cur.push_back(i);
                }
                res.push_back(cur);
                cur.clear();
            }
            while((num>sum)&&(small<(sum+1)/2))//需要减短序列
            {
                num-=small;
                small++;
                if((num==sum)&&(small<(sum+1)/2))//注意随时判断是否越界
                {
                    for(int i=small;i<=big;i++)
                    {
                        cur.push_back(i);
                    }
                    res.push_back(cur);
                    cur.clear();
                }
            }
            big++;//需要增长序列
            num+=big;
        }
        return res;
    }
};

2.翻转字符串
(1)翻转单词顺序。将I am a student.转换为student. a am I.
思路:第一步,翻转句子中所有的字符;第二步,分别翻转每个单词中字符的顺序。

class Solution {
public:
    void exChange(string &str, int s, int e)//记得加引用
    {
        while(s < e)
            swap(str[s++], str[e--]);
    }
    string ReverseSentence(string str) {
        int len=str.size();
        if(len<2) return str;
        exChange(str,0,len-1);//先整体翻转
        int start=0;
        int end=0;
        while(str[start]!='\0')
        {
            if(str[start]==' ')
            {
                start++;
                end++;
            }
            else if(str[end]==' '||str[end]=='\0')//尾部指向空格或结束字符
            {
                exChange(str,start,--end);//翻转这个单词
                start=++end;//另起一个新的单词
            }
            else
            {
                end++;
            }
        }
        return str;
    }
};

(2)左旋转字符串:把字符串前面的若干个字符转移到字符串的尾部。abcdefg 2-->cdefgab
思路:第一步,先将前面的若干个字符分成一部分,剩下的分成一部分;第二步,分别旋转这两部分;第三步,旋转整个字符串。

class Solution {
public:
    string LeftRotateString(string str, int n) {
        int len=str.length();
        if(len<2) return str;
        n%=len;
        if(n>0&&n<len)
        {
            int firstStart=0;
            int firsrEnd=n-1;
            int secondStart=n;
            int secondEnd=len-1;
            exChange(str,firstStart,firsrEnd);
            exChange(str,secondStart,secondEnd);
            exChange(str,0,len-1);
        }
        return str;
    }
    void exChange(string &str, int s, int e)//记得加引用
    {
        while(s < e)
            swap(str[s++], str[e--]);
    }
};