难度:中等
题目:
给定一个按照升序排列的整数数组 nums
,和一个目标值 target
。找出给定目标值在数组中的开始位置和结束位置。
如果数组中不存在目标值 target
,返回 [-1, -1]
。
进阶:
你可以设计并实现时间复杂度为
O(log n)
的算法解决此问题吗?
-----------------------------------
思考:
一个数组,找一个数,条件也就两个:
如果有,找出第一个和最后一个,
如果没有,就返回【-1,-1】
这特么不是送分题么?!
确实送分题!
还可以优化一下,找到以后如果后面的不等于target了就立即退出循环。
我他娘真是个天才。
代码:
public static int[] searchRange(int[] nums, int target) { int first = -1, last = -1; for (int i = 0; i < nums.length; i++) { if (nums[i] == target) { if (first == -1) first = i; last = i; } else if (nums[i] != target && last != -1) break; } return new int[]{first, last};}
直接就是反手一个合上电脑睡觉
等一下,我老。。不是,我题目呢,好像还有点东西。
呃,毕竟进阶,
如果你想做个five呢,就不进就不进了吧,有种就去睡觉
没错那个five就是我,
但不是今天。
于是又思考:
因为那个有序,还有那个找一个数字,还有,
不绕了,是个人都能看出来,二分法嘛,我们全就都用它。
折半,所以时间复杂度就是2x次方=n,x=log2n,也我们常说的就是O(logn)
代码:
public int[] searchRange(int[] nums, int target) { return new int[]{binarySearch(nums, target, true), binarySearch(nums, target, false)};}private int binarySearch(int[] nums, int target, boolean leftRight) { int left = 0, right = nums.length-1, result = -1, mid; while (left <= right) { mid = (left + right) / 2; if (nums[mid] > target) right = mid - 1; else if (nums[mid] < target) left = mid + 1; else { result = mid; if (leftRight) right = mid - 1; else left = mid + 1; } } return result;}
时间复杂度:O(n)
空间复杂度:O(1)
-----------------------------------完---------------------------------
你睇我眼神劲唔劲啊