LeetCode刷题笔记第35题

题目描述:

给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。

你可以假设数组中无重复元素。

解题思路:

最直接的想法就是使用二分查找,如果有序数组中含有与target值相等的元素,直接返回对应的索引值;如果没有则在查找完毕之后,返回对应的左游标值。还有一种解法是直接遍历有序数组,遍历进行的条件是数组当前访问值小于target值同时遍历游标小于数组长度,遍历结束后,对应的遍历游标值就是应该要返回的值。

第一种解法:二分查找

时间复杂度为:O(logn)

我在评论中看到关于计算mid值的争议,有人说直接mid = (left + right) / 2是不安全的,可能会溢出,所以一种比较安全的写法是 mid = left + (right - left) / 2; 就好比是超过10就会发生溢出,现在有两个值,一个为6,一个为8,如果直接计算,则6+8=14>10,会发生溢出,但是通过mid = left + (right - left) / 2公式进行计算 mid = 6 + (8-6)/2,就避免了这个问题,挺有道理,所以借鉴了。

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

第一种解法续:对二分查找的改进,减少循环次数

这是我在题解的评论中看到有人提供的解法,思路可以借鉴,虽然运行速度并没有我的快,哈哈哈哈

    public int searchInsert3(int[] nums,int target){
        int lo=0,hi=nums.length;
        while(lo<hi-1){
            int mid=(lo+hi)>>1;
            if(target<nums[mid])
                hi=mid;
            else
                lo=mid;
        }
        return target<=nums[lo]? lo:++lo;
    }

第二种解法:暴力遍历

超级简短,时间复杂度为O(n)

    public int searchInsert2(int[] nums, int target) {
        int i;
        for(i=0;i<nums.length&&nums[i]<target;i++);
        return i;
    }

 

posted @ 2020-03-19 23:41  有心有梦  阅读(140)  评论(0编辑  收藏  举报