算法训练第一天 | 704. 二分查找、27. 移除元素

704.二分查找:

题目链接
给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1。
示例 1:

输入: nums = [-1,0,3,5,9,12], target = 9
输出: 4
解释: 9 出现在 nums 中并且下标为 4

解答:

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

算法总结:

二分查找针对的一定是有序数组且不存在重复元素。基于以上两个条件,我们可以再考虑区间的选择问题,通常情况下写二分法,区间的定义一般为两种,左闭右闭即[left, right],或者左闭右开即[left, right),同时区间选择会影响我们编写的算法逻辑。
区间左闭右闭:
应为:1.while(left<=right)(可以假设当left=right=1时,[1,1]成立)
2.right=mid-1(因为当前区间是右闭,所以应当排除mid本身)
区间左闭右开:1.while(left 2.right=mid(因为当前区间是右开,所以通过区间已经排除mid本身)

mid的计算:本题使用的left和right作为索引,所以不考虑溢出情况,若其他情况需要考虑溢出,mid的计算应该更改为:

int mid = left + ((right - left) / 2);

相似题目:

702.搜索长度未知的有序数组
注:区别在于右边界位置,多一个循环去找到右边界即可。

283. 移除元素:

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

示例 1:

输入:nums = [3,2,2,3], val = 3
输出:2, nums = [2,2]
解释:函数应该返回新的长度 2, 并且 nums 中的前两个元素均为 2。你不需要考虑数组中超出新长度后面的元素。例如,函数返回的新长度为 2 ,而 nums = [2,2,3,3] 或 nums = [2,2,0,0],也会被视作正确答案。

解答:

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;
    }
}

算法总结:

数组移除元素第一个想到的是新建数组将其复制一遍,不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入数组,那么考虑到的就是使用双指针处理,通过一个快指针和慢指针交换处理数组的元素。

算法逻辑:慢指针一定是从下标0开始的,快指针从0开始遍历,当快指针发现val值的时候,跳过val值(如果不跳过,则会把val交换到前面)每次遍历进行一次快慢指针的交换,同时慢指针前进。

相似题目:

26.删除有序数组中的重复项
注:区别在于删除内容不同,导致快慢指针比较对象不同,保证每次比较的是上次交换的数与为交换的数即可。

你可能感兴趣的:(算法)