七月集训(5)双指针

1.LeetCode:541. 反转字符串 II

原题链接


        给定一个字符串 s 和一个整数 k,从字符串开头算起,每计数至 2k 个字符,就反转这 2k 字符中的前 k 个字符。

        如果剩余字符少于 k 个,则将剩余字符全部反转。

        如果剩余字符小于 2k 但大于或等于 k 个,则反转前 k 个字符,其余字符保持原样。

        示例 1:

        输入:s = “abcdefg”, k = 2

        输出:“bacdfeg”

        示例 2:

        输入:s = “abcd”, k = 2

        输出:“bacd”

        提示:

        1 <= s.length <= 1e4

        s 仅由小写英文组成

        1 <= k <= 1e4


        这个题还是十分简单的,按照题目每次吧2k个元素的前k个交换顺序即可,如果不够2k个元素就交换前k个

class Solution {
    void swap(string &s,int l,int r){
        while(l<=r){
            int tmp=s[l];
            s[l++]=s[r];
            s[r--]=tmp;
        }
    }
public:
    string reverseStr(string s, int k) {
        int n=s.size();
        for(int i=0;i<n;i+=2*k){
            swap(s,i,min(n-1,i+k-1));
        }
        return s;
    }
};

2.LeetCode:392. 判断子序列

原题链接


        给定字符串 s 和 t ,判断 s 是否为 t 的子序列。

        字符串的一个子序列是原始字符串删除一些(也可以不删除)字符而不改变剩余字符相对位置形成的新字符串。(例如,"ace"是"abcde"的一个子序列,而"aec"不是)。

        示例 1:

        输入:s = “abc”, t = “ahbgdc”

        输出:true

        示例 2:

        输入:s = “axc”, t = “ahbgdc”

        输出:false

        提示:

        0 <= s.length <= 100

        0 <= t.length <= 10^4

        两个字符串都只由小写字符组成。


        本题只需要找一个字符串是否是t的子序列,那么直接遍历即可。

class Solution {
public:
    bool isSubsequence(string s, string t) {
        int i=0,j=0;
        while(s[i]&&t[j]){
            if(s[i]==t[j]) ++i;
            ++j;
        }
        return i==s.size();
    }
};

3.LeetCode:面试题 16.24. 数对和

原题链接


        设计一个算法,找出数组中两数之和为指定值的所有整数对。一个数只能属于一个数对。

        示例 1:

        输入: nums = [5,6,5], target = 11

        输出: [[5,6]]

        示例 2:

        输入: nums = [5,6,5,6], target = 11

        输出: [[5,6],[5,6]]

        提示:

        nums.length <= 100000


        这道题老两数之和了,先排序然后查找数对即可。

class Solution {
public:
    vector<vector<int>> pairSums(vector<int>& nums, int target) {
        vector<vector<int>> ans;
        int l=0,r=nums.size()-1;
        sort(nums.begin(),nums.end());
        while(l<r){
            int cur=nums[l]+nums[r];
            if(cur>target){
                r--;
            }if(cur<target){
                ++l;
            }else {
                ans.push_back({nums[l++],nums[r--]});
            }
        }
        return ans;
    }
};

4.LeetCode:696. 计数二进制子串

原题链接


        给定一个字符串 s,统计并返回具有相同数量 0 和 1 的非空(连续)子字符串的数量,并且这些子字符串中的所有 0 和所有 1 都是成组连续的。

        重复出现(不同位置)的子串也要统计它们出现的次数。

        示例 1:

        输入:s = “00110011”

        输出:6

        示例 2:

        输入:s = “10101”

        输出:4

        提示:

        1 <= s.length <= 1e5

        s[i] 为 ‘0’ 或 ‘1’


        这道题还是比较有意思的,以一个示例来讲解:00110011.

        他的答案是6,这六个字符串从左往右分别是 01([1,2]),0011([0,3]),10([3,4]),1100([2,5]),01([5,6]),0011([4,7])。

        现在我们把这个序列连续的0或1按顺序放到一个数组中,那么数组中的元素就是 2 ,2,2,2。这里相邻的两个元素都代表着原序列中不同的数字,比如本例子中分别代表着原数组中按顺序的 0,1,0,1。

        那么他们怎样构成答案的呢,也很简单。比如2,2所代表的0011或者1100,交界处的 01或者10首先符合要求,再往前看0011或者1100也符合要求,而如果2 ,3所代表的00111交界处的01,再往前的0011,就是这个序列组成的答案数目。

        如果还不明白的话看下图的这个示例在这里插入图片描述

        他的答案是11,分别是01,0011,10,1100,01,0011,10,1100,01,0011,000111,原字符串中连续的0或1连续按顺序分组情况是2,2,2,2,4,3。分别代表着00,11,00,11,0000,111,每相邻两个元素代表原字符串中相邻的连续的0和1或者1和0的个数,现在从交界地往前看,符合答案的序列就是01,0011,000111…(依次类推)这样不难发现,每相邻连续的0和1序列或者1和0序列组成的答案数目就是这两个元素的最小值。

class Solution {
    vector<int> cnt;
public:
    int countBinarySubstrings(string s) {
        for(int i=0;i<s.size();++i){
            int count=1;
            while(s[i+1]==s[i]){
                ++count;
                ++i;
            }
            cnt.push_back(count);
        }
        int ans=0;
        for(int i=1;i<cnt.size();++i){
            ans+=min(cnt[i],cnt[i-1]);
        }
        return ans;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值