704.二分查找|27.移除元素【算法学习笔记】

1,113 阅读2分钟

704.二分查找|27.移除元素【算法学习笔记】

  1. 二分查找法 通过与中间元素的比较判断目标元素在哪个区间,逐步缩小查找区间直至left=right,最后这个下标的元素就是我们要查找的值
class Solution {
    public int search(int[] nums, int target) {
        int left = 0;
        int right = nums.length - 1;
        if (target < nums[0] || target > nums[nums.length - 1]) {
            return -1;}
        while (left <= right) {
            int middle = (left + right) / 2;
            if (target < nums[middle]) {
                right = middle - 1;
            }
            else if (target > nums[middle]) {
                left = middle + 1;
            }
            else
                return middle;
        }
        return -1;
    }
  1. 移除元素 这道题的要求是在nums这个数组找到等于val的元素,并原地移除它

第一种解法是 暴力解法,通过第一次for循环遍历数组,再用一次for循环将后面的元素往前移,需要注意的第一点是在移动时到后面的元素不能越界,第二点是,移动后面的元素相当于i向前移动一位,需要i--,第三点是,size记得变化。

class Solution {
    public int removeElement(int[] nums, int val) {
        int size = nums.length;
        for (int i = 0; i < size; i++) {   //第一遍for循环遍历数组
            if (nums[i] == val) {         //遇到删除元素,删除它并且后面元素向前移动一位
                for (int j = i+1 ; j < size; j++) {
                    nums[j-1] = nums[j];
                }
                i--;   //i--保证下次循环依旧从删除位置开始
                size--;
            }
        }
        return size;
    }
};

第二种解法是 双指针解法,又称快慢指针解法,慢指针指向要更新元素的位置,快指针指向用于替换旧元素的位置。

要理解的是区别于暴力解法,这个解法相当于用两个指针,当快指针没有遇到目标元素时,和慢指针一起前进,当遇到目标元素后就把快指针指向的元素赋给慢指针,这样就形成了一个错位,持续的更新数组元素,直到快指针指向最后一个元素,这时候慢指针指向的元素位置就是最后的长度。

class Solution {
    public int removeElement(int[] nums, int val) {
        // 快慢指针
        int slowIndex = 0;  //慢指针指向更新数组的位置
        //快指针用来替换慢指针位置的元素
        for (int fastIndex = 0; fastIndex < nums.length; fastIndex++) {
            if (nums[fastIndex] != val) {    //当遇到要删除的元素时,跳过,否则更新数组,慢指针+1
                nums[slowIndex] = nums[fastIndex];
                slowIndex++;
            }
        }
        return slowIndex;
    }
}