《六月集训》(第五天)——双指针

前言

        欢迎大家积极在评论区留言发表自己的看法,知无不言,言无不尽,养成每天刷题的习惯,也可以自己发布优质的解题报告,供社区一同鉴赏,吸引一波自己的核心粉丝。
        今天是六月集训第五天:双指针🔥🔥🔥
在这里插入图片描述

一、练习题目

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

二、算法思路

  • 1、2000. 反转单词前缀:先遍历看看能不能找到目标字符,如果遍历完整一个字符串都找不到,就直接返回原串;如果找到我们记录下标位置为j,然后在 [ 0 , j ] [0,j] [0,j]范围内进行交换。🔥
  • 2、917. 仅仅反转字母:五月集训做过了。🔥
  • 3、475. 供暖器:这题和后面一题花了点时间,这两题的思路很像,思路是遍历每一个房子,二分的加热器数组中离得房子最近的一个加热器所需的范围,然后再返回最小范围中的最大值就是能够满足所有范围的那一个,是一个 m a x ( m i n ( ) ) max(min()) max(min())问题。这里要主要两边界最左和最右,他们的左端和右端都是无穷需要单独处理否则数组越界的。🔥🔥🔥🔥
  • 4、面试题 16.06. 最小差:这题可以用上一题的思路,但是求的一个最小值。然后我用了一个双指针的方法来做。同时为了防止越界直接上long来处理了。🔥🔥🔥🔥

三、源码剖析

// 2000. 反转单词前缀]
class Solution {
public:
    string reversePrefix(string word, char ch) {
        int n = word.size();
        int i, j = 0;
        while(j < n) {
            if(word[j] == ch) {
                break;
            }
            j++;
        }

        if(j == n) {
            return word;
        }

        for(i = 0; i < j; i++, j--) {
            swap(word[i], word[j]);
        }
        return word;
    }
};
  • 1、简单题写在思路分析中。
// 917. 仅仅反转字母
class Solution {
public:
    string reverseOnlyLetters(string s) {
        int i = 0, j = s.length() - 1;
        while(i < j) {
            if(isalpha(s[i]) && isalpha(s[j])) {
                swap(s[i], s[j]);
                ++i, --j;
            } else if(!isalpha(s[i])) {
                ++i;
            } else if(!isalpha(s[j])) {
                --j;
            } else {
                ++i, --j;
            }
        }
        return s;
    }
};
  • 1、可以看五月集训的内容。
// 475. 供暖器
class Solution {
public:
    int findRadius(vector<int>& houses, vector<int>& heaters) {
        sort(houses.begin(), houses.end());
        sort(heaters.begin(), heaters.end());
        int x, ret = 0;
        for(int i = 0; i < houses.size(); ++i) {
            if(houses[i]  < heaters[0]) {
                x = heaters[0] - houses[i]; //(1)
            } else if(houses[i] > heaters.back()) {
                x = houses[i] - heaters.back();
            } else {
                int ans = -1;
                int l = 0, r = heaters.size() - 1;
                while(l <= r) {
                    int mid = (l + r) >> 1;
                    if(heaters[mid] <= houses[i]) {
                        l = mid + 1;
                        ans = mid;
                    } else {
                        r = mid - 1;
                    }
                }
                if(ans == heaters.size() -1) {
                    x = houses[i] - heaters[ans];
                } else {
                    x = min(heaters[ans+1] - houses[i], houses[i] - heaters[ans]);
                }
            }
            ret = max(x, ret);
        }
        return ret;
    }
};
  • 1、见算法思路。
// 面试题 16.06. 最小差
class Solution {
public:
    int smallestDifference(vector<int>& a, vector<int>& b) {
        sort(a.begin(), a. end());
        sort(b.begin(), b. end()); //(1)
        int n = a.size(), m = b.size(), i = 0, j = 0;
        long ret = LONG_MAX;
        while(i < n && j < m) {
            if(a[i] != b[j]) { //(2)
                ret = min(ret, (long)abs(a[i] - b[j]));
                a[i] > b[j] ? j++ : i++;
            } else {
                return 0;
            }
        }
        return ret;
    }
};
  • 1、先排序
  • 2、两个不相等,就取绝对值,并与结果取最小值,比较当前数的大小,把小的那个指针往右移,因为要找差的最小值,尽量缩小差值。如果有数相等直接返回0,因为0肯定是最小的差值,这里有点贪心的思想。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值