[Swift]LeetCode33. 搜索旋转排序数组 | Search in Rotated Sorted Array
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
➤微信公众号:山青咏芝(shanqingyongzhi)
➤博客园地址:山青咏芝(https://www.cnblogs.com/strengthen/)
➤GitHub地址:https://github.com/strengthen/LeetCode
➤原文地址:https://www.cnblogs.com/strengthen/p/9899997.html
➤如果链接不是山青咏芝的博客园地址,则可能是爬取作者的文章。
➤原文已修改更新!强烈建议点击原文地址阅读!支持作者!支持原创!
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
Suppose an array sorted in ascending order 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.
Your algorithm's runtime complexity must be in the order of O(log n).
Example 1:
Input: nums = [4,5,6,7,0,1,2]
, target = 0
Output: 4
Example 2:
Input: nums = [4,5,6,7,0,1,2]
, target = 3
Output: -1
假设按照升序排序的数组在预先未知的某个点上进行了旋转。
( 例如,数组 [0,1,2,4,5,6,7]
可能变为 [4,5,6,7,0,1,2]
)。
搜索一个给定的目标值,如果数组中存在这个目标值,则返回它的索引,否则返回 -1
。
你可以假设数组中不存在重复的元素。
你的算法时间复杂度必须是 O(log n) 级别。
示例 1:
输入: nums = [4,5,6,7,0,1,2]
, target = 0
输出: 4
示例 2:
输入: nums = [4,5,6,7,0,1,2]
, target = 3
输出: -1
12ms
1 class Solution { 2 func search(_ nums: [Int], _ target: Int) -> Int { 3 guard nums.count > 0 else { return -1 } 4 return search(0, nums.count - 1, nums, target) ?? -1 5 } 6 7 func search(_ start: Int, _ end: Int, _ nums: [Int], _ target: Int) -> Int? { 8 9 if (start == end) { 10 if nums[start] == target { 11 return start 12 } else { 13 return nil 14 } 15 } 16 17 let mid = (start + end) / 2 18 19 //if start to mid is sorted 20 if nums[start] <= nums[mid] { 21 if target >= nums[start] && target <= nums[mid] { 22 return search(start, mid, nums, target) 23 } else { 24 return search(mid + 1, end, nums, target) 25 } 26 27 } 28 29 //if mid to end is sorted 30 if target >= nums[mid + 1] && target <= nums[end] { 31 return search(mid + 1, end, nums, target) 32 } else { 33 return search(start, mid, nums, target) 34 } 35 } 36 37 }
12ms
1 class Solution { 2 func search(_ nums: [Int], _ target: Int) -> Int { 3 if nums.count <= 0 { 4 return -1 5 } 6 7 if nums.first! == target { 8 return 0 9 } 10 11 if nums.last! == target { 12 return nums.count - 1 13 } 14 15 var low = 0 16 var high = nums.count - 1 17 var mid = (low + high) >> 1 18 while low <= high { 19 let vallow = nums[low] 20 let valhigh = nums[high] 21 let valmid = nums[mid] 22 23 if vallow == target { 24 return low 25 } 26 if valhigh == target { 27 return high 28 } 29 if valmid == target { 30 return mid; 31 } 32 33 if target > valhigh { 34 if target > vallow { 35 if target > valmid { 36 low += 1 37 high -= 1 38 } else { 39 high = mid - 1 40 low += 1 41 } 42 } 43 } else { 44 if target > vallow { 45 if target > valmid { 46 low = mid + 1; 47 } else { 48 high = mid - 1 49 } 50 } else { 51 low += 1 52 high -= 1 53 } 54 } 55 mid = (low + high) >> 1 56 if target > valhigh && target < vallow { 57 return -1 58 } 59 } 60 return -1 61 } 62 }
16ms
1 class Solution { 2 func search(_ nums: [Int], _ target: Int) -> Int { 3 var left = 0 4 var right = nums.count - 1 5 var mid = 0 6 7 while left <= right { 8 mid = (right - left) / 2 + left 9 10 if nums[mid] == target { 11 return mid 12 } 13 14 if nums[mid] >= nums[left] { 15 if nums[mid] > target && target >= nums[left] { 16 right = mid - 1 17 } else { 18 left = mid + 1 19 } 20 } else { 21 if nums[mid] < target && target <= nums[right] { 22 left = mid + 1 23 } else { 24 right = mid - 1 25 } 26 } 27 } 28 return -1 29 } 30 }
16ms
1 class Solution { 2 func search(_ nums: [Int], _ target: Int) -> Int { 3 if nums.count == 0 { 4 return -1 5 } 6 7 var left = 0 8 var right = nums.count - 1 9 var middle = 0 10 11 while left < right { 12 middle = (left + right) / 2 13 if nums[middle] == target { 14 return middle 15 } 16 if nums[left] <= nums[middle] { 17 if target >= nums[left] && target < nums[middle] { 18 right = middle - 1 19 } else { 20 left = middle + 1 21 } 22 } else { 23 if target > nums[middle] && target <= nums[right] { 24 left = middle + 1 25 } else { 26 right = middle - 1 27 } 28 } 29 } 30 31 return nums[left] == target ? left : -1 32 } 33 }
20ms
1 class Solution { 2 func search(_ nums: [Int], _ target: Int) -> Int { 3 4 if nums.count == 0 5 { 6 return -1 7 } 8 var pivot = 0 9 if nums.count < 3 10 { 11 for i in 0..<nums.count 12 { 13 if nums[i] == target 14 { 15 return i 16 } 17 } 18 return -1 19 } 20 21 if nums.first == target 22 { 23 return 0 24 } 25 if nums.last == target 26 { 27 return nums.count-1 28 } 29 for i in 1..<nums.count-1 30 { 31 if nums[i-1] > nums[i] && nums[i] < nums[i+1] 32 { 33 pivot = i 34 } 35 } 36 37 var desSortedArr = Array(nums[0..<pivot]) 38 var acsSortedArr = Array(nums[pivot...nums.count-1]) 39 //print(desSortedArr) 40 let indexA = acsBinarySearch(desSortedArr,0,desSortedArr.count-1,target) 41 let indexB = acsBinarySearch(acsSortedArr,0,acsSortedArr.count-1,target) 42 43 //print("pivot\(pivot)") 44 //print("indexA\(indexA)") 45 //print("indexB\(indexB)") 46 if indexA >= 0 47 { 48 return indexA 49 }else if indexB >= 0 50 { 51 return desSortedArr.count + indexB 52 } 53 return -1 54 } 55 56 func descBinarySearch(_ arr:[Int] , _ lo:Int,_ hi:Int, _ target:Int) -> Int 57 { 58 59 if lo <= hi 60 { 61 var mi = (lo+hi)/2 62 63 if arr[mi] == target 64 { 65 print("arr[mi]\(arr[mi])") 66 return mi 67 } 68 else if target > arr[mi] 69 { 70 71 if mi - 1 >= lo 72 { 73 return descBinarySearch(arr,lo,mi-1,target) 74 } 75 } 76 else if target < arr[mi] 77 { 78 if mi + 1 <= hi 79 { 80 return descBinarySearch(arr,mi+1,hi,target) 81 } 82 } 83 } 84 return -1 85 } 86 87 func acsBinarySearch(_ arr:[Int] , _ lo:Int,_ hi:Int, _ target:Int) -> Int 88 { 89 90 if lo <= hi 91 { 92 var mi = (lo+hi)/2 93 94 if arr[mi] == target 95 { 96 return mi 97 } 98 else if target > arr[mi] 99 { 100 if mi + 1 <= hi 101 { 102 return acsBinarySearch(arr,mi+1,hi,target) 103 } 104 } 105 else if target < arr[mi] 106 { 107 108 if mi - 1 >= lo 109 { 110 return acsBinarySearch(arr,lo,mi-1,target) 111 } 112 113 } 114 } 115 return -1 116 } 117 }
32ms
1 class Solution { 2 func search(_ nums: [Int], _ target: Int) -> Int { 3 var start = 0 4 var end = nums.count-1 5 6 while start <= end { 7 let mid = start + (end - start)/2 8 if nums[mid] == target { 9 return mid 10 } 11 12 if nums[mid] >= nums[start] { // 前半段排好序 13 if nums[mid] > target && nums[start] <= target { 14 end = mid-1 15 } 16 else { 17 start = mid+1 18 } 19 } 20 else { // 后半段排好序 21 if nums[mid] < target && nums[end] >= target { 22 start = mid+1 23 } 24 else { 25 end = mid-1 26 } 27 } 28 } 29 30 return -1 31 } 32 }