-
Notifications
You must be signed in to change notification settings - Fork 62
/
SearchinRotatedSortedArray.cpp
154 lines (117 loc) · 3.7 KB
/
SearchinRotatedSortedArray.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
/*
Source: https://leetcode.com/problems/search-in-rotated-sorted-array/
Time: O(log base2 n), where n is the size of the given vector(nums) and (log base2 n) is the maximum possible iterations
Space: O(1), in-place
*/
// commented solution
class Solution {
public:
int search(vector<int>& nums, int target) {
int end = nums.size() - 1;
// if the array is not rotated i.e. if the array is strictly increasing[eg: {1,2,3,4}], then
if(nums[0] < nums[end]) {
return indexOfTarget(nums, 0, end, target); // directly return the index of target if present, else return -1
}
// find the index of minimum element in nums
int start = 0;
int firstElement = nums[0];
while(start < end) {
int mid = (start + end) >> 1;
// if the current element is minimum, then store it's index and stop iteration
if(mid > 0 && nums[mid] < nums[mid - 1]) {
start = mid;
break;
}
if(nums[mid] >= firstElement) { // to search in right sorted part
start = mid + 1;
} else { // to search in left sorted part
end = mid;
}
}
// store the index of min element in nums
int indexOfMinElement = start;
// if the minimum element is equal to the the target, then directly return it's index
if(nums[indexOfMinElement] == target) {
return indexOfMinElement;
}
start = 0;
end = nums.size() - 1;
// if the target element is on the right sorted part, then
if(target < firstElement) {
start = indexOfMinElement; // search from index of minimum element to the end of the array(nums)
} else { // if the target element is on the left side of the sorted array
end = indexOfMinElement - 1; // search from 0 to one previous element from index of minimum element
}
// now as we know which sorted part(left or right) to search, do standard binary search
// search for the index of target if the target is present in the nums, else return -1
return indexOfTarget(nums, start, end, target);
}
// standard binary search
private:
int indexOfTarget(vector<int>& nums, int start, int end, int target) {
while(start <= end) {
int mid = (start + end) >> 1;
if(nums[mid] == target) {
return mid;
}
if(nums[mid] < target) {
start = mid + 1;
} else {
end = mid - 1;
}
}
return -1;
}
};
------------------------------------------------------------------------------------------------------------------------------------------------------------
// solution without comments
class Solution {
public:
int search(vector<int>& nums, int target) {
int end = nums.size() - 1;
if(nums[0] < nums[end]) {
return indexOfTarget(nums, 0, end, target);
}
int start = 0;
int firstElement = nums[0];
while(start < end) {
int mid = (start + end) >> 1;
if(mid > 0 && nums[mid] < nums[mid - 1]) {
start = mid;
break;
}
if(nums[mid] >= firstElement) {
start = mid + 1;
} else {
end = mid;
}
}
int indexOfMinElement = start;
if(nums[indexOfMinElement] == target) {
return indexOfMinElement;
}
start = 0;
end = nums.size() - 1;
if(target < firstElement) {
start = indexOfMinElement;
} else {
end = indexOfMinElement - 1;
}
return indexOfTarget(nums, start, end, target);
}
private:
int indexOfTarget(vector<int>& nums, int start, int end, int target) {
while(start <= end) {
int mid = (start + end) >> 1;
if(nums[mid] == target) {
return mid;
}
if(nums[mid] < target) {
start = mid + 1;
} else {
end = mid - 1;
}
}
return -1;
}
};