1.和为k的子数组
给定一个整数数组和一个整数 k,你需要找到该数组中和为 k 的连续的子数组的个数。
示例 1 :
输入:nums = [1,1,1], k = 2
输出: 2 , [1,1] 与 [1,1] 为两种不同的情况。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/subarray-sum-equals-k
方法一:暴力枚举:两层循环,第一层start从0-len-1,第二层end从start到0,这样可以遍历所有的数组.

class Solution {
public:
    int subarraySum(vector<int>& nums, int k) {
        int len=nums.size();
        int count=0;
        for(int start=0;start<len;start++)//0-len-1
        {
            int sum=0;
            for(int end=start;end>=0;end--)//start-0
            {
               sum+=nums[end];
               if(sum==k)
               {
                   count++;
               }
            }
        }
        return count;
    }
};

方法二:前缀和+哈希表优化:key是前缀和,value是这个前缀和出现了几次。根据当前前缀和,在 map 中寻找【相减 === k】的目标前缀和。目标前缀和是一个数值,出现这个数值可能不止 1 次,假设为 n 次,就等价于,找到 n 个连续子数组的求和 === k,遍历 nums 数组,不断把 n 累加给 count,最后返回count

class Solution {
public:
    int subarraySum(vector<int>& nums, int k) {
        unordered_map<int, int> mp;
        mp[0] = 1;
        int count = 0, pre = 0;
        for (auto& x:nums) {
            pre += x;
            if (mp.find(pre - k) != mp.end()) count += mp[pre - k];//找到对应key值pre-k,count++
            mp[pre]++;//value++
        }
        return count;
    }
};

2.和为s的连续正数序列。
输出所有和为S的连续正数序列。序列内按照从小至大的顺序,序列间按照开始数字从小到大的顺序。

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;
    }
};

3.和为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;
    }
};

4.左旋转字符串
汇编语言中有一种移位指令叫做循环左移(ROL),现在有个简单的任务,就是用字符串模拟这个指令的运算结果。对于一个给定的字符序列S,请你把其循环左移K位后的序列输出。例如,字符序列S=”abcXYZdef”,要求输出循环左移3位后的结果,即“XYZdefabc”。是不是很简单?OK,搞定它!
思路:先翻转前面的n为字符,再翻转n位之后的所有字符,最后整体翻转。

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);//先移动前面n位
            exChange(str,secondStart,secondEnd);//再移动n位后面的所有字符
            exChange(str,0,len-1);//整体翻转
        }
        return str;
    }
    void exChange(string &str, int s, int e)//记得加引用
    {
        while(s < e)
            swap(str[s++], str[e--]);
    }
};