题目:
Suppose a sorted array is rotated at some pivot unknown to you beforehand.
(i.e., 0 1 2 4 5 6 7
might become 4 5 6 7 0 1 2
).
You are given a target value to search. If found in the array return its index, otherwise return -1.
You may assume no duplicate exists in the array.
链接: http://leetcode.com/problems/search-in-rotated-sorted-array/
题解:Rotated array中查找值,使用Binary Search,要注意数组是向左shift或者是向右shift,保持在一个单调递增的部分进行查找。
简单的三种情况 - 1) 不平移 1234567
2) 向左3位 4567123
3) 向右3位 5671234
时间复杂度 O(logn), 空间复杂度 O(1)
public class Solution {
public int search(int[] nums, int target) { //binary search
if(nums == null || nums.length == 0)
return 0;
int lo = 0, hi = nums.length - 1; while(lo <= hi) {
int mid = lo + (hi - lo) / 2;
if(nums[mid] == target)
return mid;
else if(nums[mid] < nums[hi]) { // right half sorted
if(target > nums[mid] && target <= nums[hi]) //e.g. target = 5, 1-2-3-4-5-6-7, 6-7-1-2-3-4-5
lo = mid + 1;
else //e.g target = 5, 5-6-7-1-2-3-4
hi = mid - 1;
} else { // left half sorted
if(target < nums[mid] && target >= nums[lo]) //e.g. target = 3, 3-4-5-6-7-1-2
hi = mid - 1;
else //e.g. target = 3, 4-5-6-7-1-2-3
lo = mid + 1;
}
} return -1;
}
}
二刷:
Java:
反而写得比较复杂了。不过原理就是用nums[mid]和nums[right]进行比较,保持mid左边或者右边一段是有序的,再根据target与 nums[mid] 和nums[right]的关系来完成进一步的二分。 看到3天前StefanPochmann又发了一个帖子,可以加入Integer.MIN_VALUE或者Integer.MAX_VALUE来进行普通二分,非常巧妙,放在reference里以后看。
Time Complexity - O(logn), Space Complexity - O(1)
public class Solution {
public int search(int[] nums, int target) { // assume no duplicates
if (nums == null || nums.length == 0) {
return -1;
}
int lo = 0, hi = nums.length - 1;
while (lo <= hi) {
int mid = lo + (hi - lo) / 2;
if (target == nums[mid]) {
return mid;
} else if (target < nums[mid]) {
if (nums[mid] < nums[hi]) { // right part sorted
hi = mid - 1;
} else{
if (target <= nums[hi]) {
lo = mid + 1;
} else {
hi = mid - 1;
}
}
} else {
if (nums[mid] < nums[hi]) {
if (target > nums[hi]) {
hi = mid - 1;
} else {
lo = mid + 1;
}
} else {
lo = mid + 1;
}
}
}
return -1;
}
}
题外话:
今天被Two Sigma的Recruiter联系,聊了一下之后感觉对方十分专业。打算递交简历以后再拖延一段时间,来进行复习准备。更需要练习的是反应速度,脑力,分析能力,交流能力,专注程度,以及做题的速度和准确度。
三刷:
使用了一刷的逻辑。还是Binary Search,就是先判断是否nums[mid] == target,再判断这个sorted array是向左还是右平移,哪一部分仍然是有序的。接下来根据上面的信息来判断如何二分。
Java:
Time Complexity - O(logn), Space Complexity - O(1)。
public class Solution {
public int search(int[] nums, int target) {
if (nums == null || nums.length == 0) return -1;
int lo = 0, hi = nums.length - 1;
while (lo <= hi) {
int mid = lo + (hi - lo) / 2;
if (target == nums[mid]) {
return mid;
} else if (nums[mid] < nums[lo]) { // right side sorted
if (target > nums[mid] && target <= nums[hi]) lo = mid + 1;
else hi = mid - 1;
} else { // left side sorted
if (target >= nums[lo] && target < nums[mid]) hi = mid - 1;
else lo = mid + 1;
}
}
return -1;
}
}
4/3/2016: 今天去Edison取税,之后和地图君一块吃了一家H-Mart附近的东北菜馆。人很少,周日中午加上我们一共就三桌,不过味道挺不错。 吃了烤羊肉串,豆腐脑,煎饼果子,韭菜盒子,锅包肉,地三鲜,酸菜排骨等等,特别对我的胃口。咸豆腐脑可能还是来美帝这么久第一次吃到,好羡慕住附近的朋友们。地图君坚持付了帐,下次再这样我要生气了。
Reference:
https://leetcode.com/discuss/80659/clever-idea-making-it-simple
https://leetcode.com/discuss/41134/java-ac-solution-using-once-binary-search