算法修炼day01|704. 二分查找,27. 移除元素

35 阅读2分钟

三刷代码随想录的目标:

1.题目思考要有自主性。

直接自己做,做出来用注释标出关键点。做不出来看题解,抓住问题的关键。

2.题目关键点、原理及拓展尽可能遍历到。

是区间、边界等细节问题?还是原理、方法问题?

3.做所学知识做总结。

抓住关键点

704. 二分查找 - 力扣(LeetCode)

// 关键点:区间定义左闭右闭。目的是将落单的元素也能遍历到!!!
class Solution {
    public int search(int[] nums, int target) {
        int left = 0;
        int right = nums.length - 1;
        while (left <= right) { // 之所以是≤,是为了保证范围内的最后一个元素也能被获取到
            int mid = (left + right) / 2;
            if (nums[mid] == target) {
                return mid;
            } else if (nums[mid] > target) {
                right = mid - 1;
            } else if (nums[mid] < target) {
                left = mid + 1;
            }
        }
        return -1; // 都不满足则将-1作为默认结果返回
    }
}

35. 搜索插入位置 - 力扣(LeetCode)

// 模板一样,仅仅将默认输出结果-1变为l(代表"left")!!!
class Solution {
    public int searchInsert(int[] nums, int target) {
        int l = 0;
        int r = nums.length - 1;
        int mid = 0;
        while (l <= r) { // 左闭右闭区间
            mid = (l + r) / 2;
            if (nums[mid] == target) {
                return mid;
            } else if (nums[mid] > target) {
                r = mid - 1;
            } else {
                l = mid + 1;
            }
        }
        return l; // 拿example2模拟一下就是这个结果
    }
}

34. 在排序数组中查找元素的第一个和最后一个位置 - 力扣(LeetCode)

// 二分法的模板下,遇到相等元素时,以此索引为基准分别前后进行遍历,获取区间内值相同的前后两个索引加入到结果集ans中!!!
class Solution {
    public int[] searchRange(int[] nums, int target) {
        int[] res = {-1, -1};
        int left = 0;
        int right = nums.length - 1;
        int[] ans = new int[2];
        while (left <= right) {
            int mid = (left + right) / 2;
            if (nums[mid] == target) { // 当遇到相同元素时,分别向前向后进行遍历,直到不满足条件。
                int index = mid;
                while (--index >=0 && nums[index] == target) {
                    continue;
                }
                ans[0] = index + 1; // 第一相等值的索引
                while (++mid < nums.length && nums[mid] == target) {
                    continue;
                }
                ans[1] = mid - 1; // 最后相等值的索引
                return ans;
            } else if (nums[mid] > target) {
                right = mid - 1;
            } else {
                left = mid + 1;
            }
        }
        return res;
    }
}

27. 移除元素 - 力扣(LeetCode)

题解一:这题看着竟然有点懵,本质就是遇到(!=val)的元素就执行覆盖操作,否则向后遍历即可。

题解二:遇到(==val)的元素就执行覆盖操作,否则循环遍历即可。

// 从前向后遍历和覆盖
// class Solution {
//     public int removeElement(int[] nums, int val) {
//         int left = 0;
//         for (int right = 0; right < nums.length; right++) {
//             if (nums[right] != val) { // 区别点
//                 nums[left] = nums[right];
//                 left++;
//             }
//         }
//         return left;
//     }   
// }

// 从后向前向后遍历,从后向前覆盖
class Solution {
    public int removeElement(int[] nums, int val) {
        int left = 0, right = nums.length - 1;
        while (left <= right) {
            if (nums[left] == val) { // 区别点
                nums[left] = nums[right];
                right--;
            } else {
                left++;
            }
        }
        return left;
    }   
}