代码随想录:二分查找和双指针

二分查找

lc704

c 复制代码
class Solution {
public:
    int search(vector<int>& nums, int target) {
        int left = 0, right = nums.size() - 1;
        while(left < right){
            int mid = (left + right) >> 1;  // 可以写成mid = left + (right - left) >> 1
            if(nums[mid] >= target){
                right = mid;
            }else{
                left = mid + 1;
            }
        }
        if(nums[left] == target){
            return left;
        }
        return -1;
    }
};

lc35

  • lc35
  • 思路:手写lower_bound
  • 代码
c 复制代码
class Solution {
public:
    int searchInsert(vector<int>& nums, int target) {
        // 找第一个>=target的位置
        int left = 0, right = nums.size();
        while(left < right){
            int mid = (left + right) >> 1;
            if(nums[mid] >= target){
                right = mid;
            } else{
                left = mid + 1;
            }
        }
        return left;
    }
};

lc34

  • lc34
  • 和y总的二分例题一样
  • 代码
c 复制代码
class Solution {
public:
    vector<int> searchRange(vector<int>& nums, int target) {
        if(nums.empty()){
            return {-1, -1};
        }
        // lower_bound和upper_bound,注意二分计算时mid的溢出
        // 1. 第一个位置
        int left = 0, right = nums.size() - 1;
        while(left < right){
            int mid = left + (right - left) / 2;
            if(nums[mid] >= target){
                right = mid;
            }else{
                left = mid + 1;
            }
        }
        if(nums[left] != target){
            // 返回[-1, -1]
            return {-1, -1};
        }
        int first = left;  // 记录第一个位置
        left = 0, right = nums.size() - 1;
        // 2. 最后一个位置
        while(left < right){
            int mid = left + (right - left + 1) / 2;
            if(nums[mid] <= target){
                left = mid;
            }else{
                right = mid - 1;
            }
        }
        // 返回结果
        return {first, left};
    }
};

lc69

  • lc69
  • 回忆浮点数二分:保证一定精度内正确;但这题使用整数二分即可
  • 代码
c 复制代码
class Solution {
public:
    int mySqrt(int x) {
        int left = 0, right = 1e9;
        while(left < right){
            int mid = (right + left + 1) / 2;
            if((long long)mid * mid <= x){  // 舍去小数,所以找小于的一边
                left = mid;
            }else{
                right = mid - 1;
            }
        }
        return left;
    }
};

lc367

c 复制代码
class Solution {
public:
    bool isPerfectSquare(int num) {
        // 暴力:遍历所有int看是否平方 == num;所以使用二分简化
        int left = 1, right = 1e9;
        while(left < right){
            int mid = (left + right) >> 1;
            if((long long)mid * mid >= num){
                right = mid;
            }else{
                left = mid + 1;
            }
        }
        if((long long)left * left == num){
            return true;
        }
        return false;
    }
};

快慢指针

lc27

  • lc27
  • 暴力解:双重for,遍历到val就全部元素往前移一个位置,时间复杂度为O(n^2)
  • 优化思路:弄懂快慢指针含义即可,时间复杂度为O(n)
    • fast: 原数组位置,寻找不为val值的元素
    • slow:最终的目标数组位置
    • 变化:fast指向的不是val的元素放到slow处
  • 代码
c 复制代码
class Solution {
public:
    int removeElement(vector<int>& nums, int val) {
        int fast = 0, slow = 0; 
        for(; fast < nums.size(); fast++){
            if(val != nums[fast]){
                nums[slow++] = nums[fast];
            }
        }
        return slow;
    }
};

lc26

  • 题目
  • 上一题的变形,主要理解快慢指针的含义和他们之间的关系
  • 代码
c 复制代码
class Solution {
public:
    int removeDuplicates(vector<int>& nums) {
        if(nums.empty()){
            return 0;
        }
        // 快指针:指向原数组,找到第一个不同的元素
        // 慢指针:指向结果数组的位置
        // 如果nums[fast] != nums[fast - 1],就把这个不重复元素送到slow位置
        int slow = 1, fast = 1;
        for(; fast < nums.size(); fast++){
            if(nums[fast] != nums[fast -1]){
                nums[slow++] = nums[fast];
            }
        }
        return slow;
    }
};

lc844

  • lc844
  • 思路1:利用上面快慢指针的思想,分别得到两个最终的字符串后,再比较,时间复杂度为O(n+m);也可以用栈的思路获取最终的字符串
  • 代码:
c 复制代码
class Solution {
public:
    bool backspaceCompare(string s, string t) {
        // 1. 先去掉退格字符
        int change_s = changeString(s);
        int change_t = changeString(t);
        cout << "s = " << s << " t = " << t << endl;
        cout << change_s << ' ' << change_t << endl;
        // 2. 比较前几个字符是否相同
        if(change_s != change_t){
            return false;
        }
        for(int i = 0; i < change_s; i++){
            if(s[i] != t[i]){
                return false;
            }
        }
        return true;
    }
    int changeString(string &str){
        // 返回前几个字符是有效的
        int slow = 0, fast = 0;
        for(; fast < str.size(); fast++){
            if(str[fast] == '#'){
                if(slow != 0){  // 如果slow已经在开头,不用动
                    --slow;
                }
            } else{
                str[slow++] = str[fast];
            }
        }
        return slow;
    }
};

lc977

  • lc977
  • 思路:相向指针,因为负数平方从大到小,正数平方从小到大;两个指针比较即两个数的平方比较,大的一个放到目标数组中
  • 代码
c 复制代码
class Solution {
public:
    vector<int> sortedSquares(vector<int>& nums) {
        // 暴力:平方后排序
        // for(auto &i : nums){
        //     i = i * i;
        // }
        // sort(nums.begin(), nums.end());
        // return nums;
        // 双指针:两头指针,大的放到后面
        int n_size = nums.size() - 1;
        vector<int> ret(n_size + 1);
        for(int i = 0, j = n_size, pos = n_size; i <= j; ){
            if(nums[i] * nums[i] <= nums[j] * nums[j]){
                ret[pos--] = nums[j] * nums[j];
                j--;
            } else{
                ret[pos--] = nums[i] * nums[i];
                i++;
            }
        }
        return ret;
    }
};
相关推荐
Re.不晚几秒前
Java入门15——抽象类
java·开发语言·学习·算法·intellij-idea
ULTRA??9 分钟前
C加加中的结构化绑定(解包,折叠展开)
开发语言·c++
凌云行者1 小时前
OpenGL入门005——使用Shader类管理着色器
c++·cmake·opengl
凌云行者1 小时前
OpenGL入门006——着色器在纹理混合中的应用
c++·cmake·opengl
为什么这亚子1 小时前
九、Go语言快速入门之map
运维·开发语言·后端·算法·云原生·golang·云计算
1 小时前
开源竞争-数据驱动成长-11/05-大专生的思考
人工智能·笔记·学习·算法·机器学习
~yY…s<#>1 小时前
【刷题17】最小栈、栈的压入弹出、逆波兰表达式
c语言·数据结构·c++·算法·leetcode
可均可可2 小时前
C++之OpenCV入门到提高004:Mat 对象的使用
c++·opencv·mat·imread·imwrite
幸运超级加倍~2 小时前
软件设计师-上午题-16 算法(4-5分)
笔记·算法
白子寰2 小时前
【C++打怪之路Lv14】- “多态“篇
开发语言·c++