LeetCode简单篇----4----搜索插入位置

参考地址:https://leetcode-cn.com/problems/search-insert-position/solution/te-bie-hao-yong-de-er-fen-cha-fa-fa-mo-ban-python-/

目录

一、需求

二、暴力查找(复杂版)

思路分析

代码实现

复杂度分析

三、暴力查找(简化版)

思路分析

代码实现

复杂度分析

四、二分查找(方式1)

思路分析

代码实现

复杂度分析

 五、二分查找(方式2)

思路分析

代码实现

复杂度分析


一、需求

       A:给定一个排序数组(由小到大)和一个目标值,在数组中找到目标值,并返回其索引;

       B:若目标值不存在于数组中,返回它将会被按顺序插入的位置;

       C:假设数组中无重复元素;

二、暴力查找(复杂版)

  • 思路分析

       A:利用for循环对数组进行遍历,若找到目标值,则返回索引;

       B:若数组中无目标值

         a:若目标值小于数组第一个元素,则返回0;

         b:若目标值大于数组最后一个元素,则返回数组长度;

         c:若目标值在数组数据之间,则返回该插入位置的索引;

  • 代码实现

public int searchInsert(int[] nums, int target) {
		int i = 0, j = 0;
		for (i = 0; i < nums.length; i++) {
			if (nums[i] == target) {
				return i;
			}
		}
		// 数组中没有目标值
		if (target < nums[0]) {
			return 0;
		} else if (target > nums[i - 1]) {
			return i;
		} else {
			for (j = 0; j < i; j++) {
				if (target > nums[j] && target < nums[j + 1]) {
					return j + 1;
				}
			}
		}
		throw new IllegalArgumentException("No searchInsert solution");
	}
  • 复杂度分析

       A:时间复杂度为O(n);

       B:空间复杂度为O(1);

三、暴力查找(简化版)

  • 思路分析

       A:前面暴力破解法程序的可读性太差,需要进一步优化;

       B:利用for循环得到每一个数组值与target进行比较

         a:数组值大于等于target,那么直接返回该数组值对应的下标;

         b:若没有大于target的,那么就返回数组长度;

  • 代码实现

public int searchInsert(int[] nums, int target) {
        int i;
        for(i=0;i<nums.length;i++) {
            if(nums[i]>=target) {
                return i;
            }
        }
        return i;
}
  • 复杂度分析

       A:时间复杂度为O(n);

       B:空间复杂度为O(1);

四、二分查找(方式1)

  • 思路分析

       A:定义相关变量left和right以及mid用于二分查找,并进行初始化;

       B:比较target与数组最后一个元素,若target大,则直接返回数组长度;

       C:利用循环进行查找,若target找到了目标值,那就返回当前目标值的下标;

          若target要大于目标值,则缩小查找范围使得left=mid+1;

          若target要小于目标值,则缩小查找范围使得right=mid-1;

       D:最后的返回值问题,如何证明返回left就是待插入位置?

          这个目前还不明白,绕不过来;只能举例子,穷举法;

  • 代码实现

public int searchInsert(int[] nums, int target) {
        int left=0;
        int right = nums.length-1;

        if(target>nums[nums.length-1]) {
            return nums.length;
        }

        while(left<=right) {
            int mid = (left+right)/2;
            if(target==nums[mid]) {
                return mid;
            } else if(target>nums[mid]) {
                left=mid+1;
            } else {
                right=mid-1;
            }
        }
        return left;
    }
  • 复杂度分析

       A:时间复杂度为O(logn);

       B:空间复杂度为O(1);

 五、二分查找(方式2)

  • 思路分析

       A:上述算法在返回值上容易出问题,这里改进一下;

       B:同样,定义left,right并初始化,判断目标值是否数组最后的元素,大于就返回数组长度;

       C:循环的条件由left<=right改为left<right,这样退出循环,就不用担心返回谁了;

       D:循环中定义mid并初始化;

       E:当target要大于nums[mid]时,这时候left=mid+1,从而改变查找范围;

       F:当target要小于等于nums[mid]时,这时候right=mid,使查找范围变为[left,mid];

       G:最后返回left(right)均可;

  • 代码实现

public int searchInsert(int[] nums, int target) {
        int left = 0;
        int right = nums.length-1;
        
        if(target > nums[right]) {
            return nums.length;
        }

        while(left < right) {
            int mid = left + (right - left)/2;
            if(target > nums[mid]) {
                left = mid + 1;
            } else {
                right = mid;
            }
        }
        return left; 
    }
  • 复杂度分析

       A:时间复杂度为O(logn);

       B:空间复杂度为O(1);

发布了62 篇原创文章 · 获赞 9 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/Sruggle/article/details/103827120