前言
Algorithms + Data Structures = Programs.
————Pascal之父 Nicklaus Wirth
算法 + 数据结构 = 程序
坚持刷算法题,变得更强!
本篇博客将用两种方法解题!带你感受不一样的思路
题目及解析
解题目标:当此数组中有一个元素值等于给定的target值,返回其下标,如果数组元素中没有元素值等于target值,则返回插入位置的下标。
肯定不是随便插入,必须保证插入此值后,数组依然保持元素值从大到小排序。
思路
因为题目要求我们用时间复杂度为O(log n)来解题,所对应的其实就是二分查找,首先我们先定义左右下标用来查找,分别是left和right,再定义一个中间下标mid,让mid去找下一次寻找下标的区间。
left从0开始,right则从数组长度减1开始。这样我们就设想一个循环,不断地进行mid =(left+right)/ 2 的运算,直到找到那个元素的下标或者适合插入的位置下标为止!
情况 1:如果当前 nums[mid] 值小于 target,那么 mid 以及 mid 左边的所有元素就一定不是「插入元素的位置」,因此下一轮搜索区间是 [mid + 1..right],下一轮把 left 移动到 mid + 1 位置,所以 left = mid + 1;
情况 2:如果 nums[mid] 值大于等于 target,那么 mid 可能是「插入元素的位置」,mid 的右边一定不存在「插入元素的位置」。如果 mid 的左边还是不存在「插入元素的位置」,我们才可以真的说 mid 是「插入元素的位置」。因此下一轮搜索区间是 [left..mid],下一轮把 right 移动到 mid 位置,所以 right = mid。最后我们就可以确定插入元素的位置了。
解题代码
classSolution { publicintsearchInsert(int[] nums, inttarget) { intlen=nums.length; // 特殊判断if (nums[len-1] <target) { returnlen; } // 程序走到这里一定有 nums[len - 1] >= target,插入位置在区间 [0..len - 1]intleft=0; intright=len-1; // 在区间 nums[left..right] 里查找第 1 个大于等于 target 的元素的下标while (left<right) { intmid=left+ (right-left) /2; if (nums[mid] <target){ // 下一轮搜索的区间是 [mid + 1..right]left=mid+1; } else { // 下一轮搜索的区间是 [left..mid]right=mid; } } returnleft; } }
第二种解题
这种解题非常简单,但缺点就是不符合题目要求中空间复杂度O(log n),只能当做一种思路给大家看看。
解题代码
classSolution { publicintsearchInsert(int[] nums, inttarget) { for(inti=0; i<nums.length;i++){ if(nums[i] >=target){ returni; } } returnnums.length; } }