代码随想录算法训练营第一天| 704. 二分查找、27. 移除元素

216 阅读2分钟

704 二分查找 代码随想录 (programmercarl.com)

这个算法思想比较简单,即先把一个无序数组排序成有序的,再将数组中间元素与target数据进行比对,若target大于中间元素,则将数组查找范围缩小至大于中间元素的半边数组,再将中间元素与target进行比对,以此类推,若直到数组大小为零(left>right)仍未找到target元素则说明数组中找不到目标元素。

以下为实现代码

class Solution {
public int search(int[] nums, int target) {
    int left=0,right=nums.length-1;
    int mid;
    while(left<=right){
        mid=(left+right)/2;
        if(target==nums[mid]) return mid;
        else if(target<nums[mid]) right=mid-1;
        else left=mid+1;
    }
    return -1;
}
}

看了代码随想录之后发现二分法如果对于有重复元素的数组,目标数据的下标可能不唯一。

另外,我发现自己最开始的写法是左闭右闭的[left,right]区间,还有一种写法是[left,right)写法,实现如下。

class Solution {
public int search(int[] nums, int target) {
    int left=0,right=nums.length;
    int mid;
    while(left<right){
        mid=(left+right)/2;
        if(target==nums[mid]) return mid;
        else if(target<nums[mid]) right=mid;
        else left=mid+1;
    }
    return -1;
}
}

27 移除元素 代码随想录 (programmercarl.com)

给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。 不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入数组。 元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。

这道题目简单解法就是暴力双循环,第一层循环遍历每个数据,发现有目标数据后进入第二层循环将后面所有数据往前移动一位,但是过于繁琐。

所以我们使用两个指针去遍历数组,一个走的较快,一个走的较慢,当没有碰到目标数据时,两个指针齐头并进,碰到目标数据时,慢指针不动,快指针继续移动,从而略过了目标数据。

以下为实现代码:

class Solution {
public int removeElement(int[] nums, int val) {
    int n = nums.length;
    int left = 0;
    for (int right = 0; right < n; right++) {
        if (nums[right] != val) {
            nums[left] = nums[right];
            left++;
        }
    }
    return left;
}
}

总结:第一天开始,题目比较简单,但是思路并不简单,再接再厉