六月集训代码打卡---DAY5

前言

        来自 英雄哪里出来 的一个 免费 集训,每天 5 5 5 点打卡学习算法(我是为了卷吗,主要是想早起 😏),希望能坚持下去。这里用来复盘每天都的打卡题目。
       今日份知识点:双指针(二分)

一、题目

题目难度
2000. 反转单词前缀⭐️
917. 仅仅反转字母⭐️
475. 供暖器⭐️⭐️⭐️
面试题 16.06. 最小差⭐️

二、算法思路

1、反转单词前缀

        (1)遍历一遍数组,如果字符串中没有目标字符,直接返回;如果存在目标字符,那么下标从 0 0 0 开始到 i i i 结束,依次交换两端的两个字符。

class Solution {
public:
    void swap(char* a, char* b) {
        char tmp = *a;
        *a = *b;
        *b = tmp;
    }
    string reversePrefix(string word, char ch) {
        int i, j;
        for (i = 0; i < word.size(); ++ i) {
            if (word[i] == ch)
                break;
        }
        if (i == word.size())
            return word;
        
        j = 0;
        while (j < i) {
            swap(&word[i--], &word[j++]);
        }
        return word;
    }
};

2、仅仅反转字母

        (1)双指针板子题,两个指针一前一后,依次往中间收,如果字符不是字母,则跳过,找到前后两端的两个字母,然后交换。

class Solution {
public:
    void swap(char* a, char* b)
    {
        char tmp = *a;
        *a = *b;
        *b = tmp;
    }
    bool isAlp(char c)
    {
        return c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z';
    }
    string reverseOnlyLetters(string s) {
        int i = 0, j = s.size() - 1;
        while (i < j) {
            if (!isAlp(s[i])) {
                ++i;
                continue;
            }
            if (!isAlp(s[j])) {
                -- j;
                continue;
            }
            swap(&s[i++], &s[j--]);
        }
        return s;
    }
};

3、供暖器

        (1)二分答案,双指针检查答案的合理性。
        (2) i i i h o u s e s houses houses 的下标, j j j h e a t e r s heaters heaters 下标,那么对于每个答案,其合理性判断如下:
                · 如果 h o u s e s ( i ) ≥ h e a t e r s ( j ) − r houses(i)\geq heaters(j)-r houses(i)heaters(j)r 并且 h o u s e s ( i ) ≤ h e a t e r s ( j ) + r houses(i)\leq heaters(j)+r houses(i)heaters(j)+r,那么判断是合法的。
                · 如果遍历过程中,有合法的情况,那么直接返回 false;如果全部的 h o u s e s houses houses 都遍历完了,那么该答案 r r r 是合法的,返回 true。

class Solution {
public:
    int findRadius(vector<int>& houses, vector<int>& heaters) {
        sort(houses.begin(), houses.end());
        sort(heaters.begin(), heaters.end());
        int l = 0, r = 1e9;
        while (l < r) {
            int mid = (l + r) >> 1;
            if (check(mid, houses, heaters)) r = mid;
            else l = mid + 1;
        }
        return r;
    }
    bool check(int r, vector<int>& houses, vector<int>& heaters) {
        for (int i = 0, j = 0; i < houses.size(); i ++) {
            while (j < heaters.size() && houses[i] > heaters[j] + r) ++ j;
            if (j < heaters.size() && heaters[j] - r <= houses[i] && houses[i] <= heaters[j] + r)
                continue;
            return false;
        }
        return true;
    }
};

4、面试题 16.06. 最小差

        (1)对数组排序,两个指针 i , j i,j i,j 分别指向两个数组,对于每一对 ( i , j ) (i,j) (i,j) ,如果 a [ i ] = = b [ j ] a[i]==b[j] a[i]==b[j],那么存在最小值 0 0 0,直接返回;如果不相等,那么首先更新答案 a n s ans ans,然后根据 a [ i ] a[i] a[i] b [ j ] b[j] b[j] 的大小更新 ( i , j ) (i,j) (i,j)

class Solution {
public:
    int smallestDifference(vector<int>& a, vector<int>& b) {
        sort(a.begin(), a.end());
        sort(b.begin(), b.end());
        long long ans = 2147483650;
        int i = 0, j = 0;
        while (i < a.size() && j < b.size()) {
            if ((long long)a[i] == (long long)b[j])
                return 0;
            else {
                ans = min(ans, abs((long long)a[i] - (long long)b[j]));
                a[i] > b[j] ? ++ j : ++ i;
            }
        }
        return ans;
    }
};

结语

        2点睡,5点起,感觉要飞升了。补觉去了。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值