Skip to content

Commit b55abbe

Browse files
[N-0] refactor 81
1 parent a58e05c commit b55abbe

File tree

1 file changed

+127
-82
lines changed
  • src/main/java/com/fishercoder/solutions

1 file changed

+127
-82
lines changed
Lines changed: 127 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -1,112 +1,92 @@
11
package com.fishercoder.solutions;
22

33
/**
4+
* 81. Search in Rotated Sorted Array II
5+
*
46
* Follow up for "Search in Rotated Sorted Array":
5-
What if duplicates are allowed?
6-
7-
Would this affect the run-time complexity? How and why?
8-
9-
Write a function to determine if a given target is in the array.
7+
* What if duplicates are allowed?
8+
* Would this affect the run-time complexity? How and why?
9+
* Write a function to determine if a given target is in the array.
1010
*/
1111
public class _81 {
1212

13-
public boolean search(int[] A, int target) {
14-
int len = A.length;
15-
if (len == 0) {
16-
return false;
17-
}
18-
if (len == 1) {
19-
if (A[0] == target) {
20-
return true;
21-
} else {
13+
public static class Solution1 {
14+
public boolean search(int[] A, int target) {
15+
int len = A.length;
16+
if (len == 0) {
2217
return false;
2318
}
24-
}
25-
int watershed = A[0];
26-
int watershedIndex = 0;
27-
for (int i = 0; i < len - 1; i++) {
28-
if (A[i] > A[i + 1]) {
29-
watershed = A[i];
30-
watershedIndex = i;
31-
System.out.println("Place 1: watershed = " + watershed
32-
+ "\twatershedIndex = " + watershedIndex);
33-
for (int j = i + 1; j < len; j++) {
34-
if (A[j] == A[i]) {
35-
watershed = A[j];
36-
watershedIndex = j;
37-
System.out.println("Place 2: watershed = " + watershed
38-
+ "\twatershedIndex = " + watershedIndex);
39-
} else {
40-
break;
19+
if (len == 1) {
20+
if (A[0] == target) {
21+
return true;
22+
} else {
23+
return false;
24+
}
25+
}
26+
int watershed = A[0];
27+
int watershedIndex = 0;
28+
for (int i = 0; i < len - 1; i++) {
29+
if (A[i] > A[i + 1]) {
30+
watershed = A[i];
31+
watershedIndex = i;
32+
System.out.println("Place 1: watershed = " + watershed
33+
+ "\twatershedIndex = " + watershedIndex);
34+
for (int j = i + 1; j < len; j++) {
35+
if (A[j] == A[i]) {
36+
watershed = A[j];
37+
watershedIndex = j;
38+
System.out.println("Place 2: watershed = " + watershed
39+
+ "\twatershedIndex = " + watershedIndex);
40+
} else {
41+
break;
42+
}
4143
}
4244
}
4345
}
44-
}
45-
System.out.println("watershed = " + watershed + "\twatershedIndex = "
46-
+ watershedIndex);
47-
if (target == watershed) {
48-
return true;
49-
} else if (target > watershed) {
50-
/*
46+
System.out.println("watershed = " + watershed + "\twatershedIndex = "
47+
+ watershedIndex);
48+
if (target == watershed) {
49+
return true;
50+
} else if (target > watershed) {
51+
/*
5152
* here is the tricky part: when target is greater than watershed,
5253
* it's also possible that this list is ZERO rotated, i.e. it didn't
5354
* rotate at all! Then at this moment, watershed is not the largest
5455
* element int this array, so we need to binary search this whole
5556
* array.
5657
*/
57-
if (watershedIndex == 0) {
58-
int start = 0;
59-
int end = len - 1;
60-
int mid = (start + end) / 2;
61-
while (start <= end) {
62-
if (target > A[mid]) {
63-
start = mid + 1;
64-
mid = (start + end) / 2;
65-
} else if (target < A[mid]) {
66-
end = mid - 1;
67-
mid = (start + end) / 2;
68-
} else if (target == A[mid]) {
69-
return true;
58+
if (watershedIndex == 0) {
59+
int start = 0;
60+
int end = len - 1;
61+
int mid = (start + end) / 2;
62+
while (start <= end) {
63+
if (target > A[mid]) {
64+
start = mid + 1;
65+
mid = (start + end) / 2;
66+
} else if (target < A[mid]) {
67+
end = mid - 1;
68+
mid = (start + end) / 2;
69+
} else if (target == A[mid]) {
70+
return true;
71+
}
7072
}
73+
return false;
74+
} else {
75+
return false;
7176
}
72-
return false;
73-
} else {
74-
return false;
75-
}
76-
} else if (target < watershed) {
77+
} else if (target < watershed) {
7778
/*
7879
* target could be in either part of this sorted array, then we
7980
* check if target is greater than A[0], if so, then search in the
8081
* first part, if not, then check if it is greater than A[len - 1],
8182
* if so, return -1, if not, search in the second part
8283
*/
8384

84-
if (target == A[0]) {
85-
return true;
86-
} else if (target > A[0]) {
87-
int start = 1;
88-
int end = watershedIndex - 1;
89-
int mid = (start + end) / 2;
90-
while (start <= end) {
91-
if (target > A[mid]) {
92-
start = mid + 1;
93-
mid = (start + end) / 2;
94-
} else if (target < A[mid]) {
95-
end = mid - 1;
96-
mid = (start + end) / 2;
97-
} else if (target == A[mid]) {
98-
return true;
99-
}
100-
}
101-
return false;
102-
} else if (target < A[0]) {
103-
if (target == A[len - 1]) {
85+
if (target == A[0]) {
10486
return true;
105-
} else if (target > A[len - 1]) {
106-
return false;
107-
} else if (target < A[len - 1]) {
108-
int start = watershedIndex + 1;
109-
int end = len - 2;
87+
} else if (target > A[0]) {
88+
int start = 1;
89+
int end = watershedIndex - 1;
11090
int mid = (start + end) / 2;
11191
while (start <= end) {
11292
if (target > A[mid]) {
@@ -120,10 +100,75 @@ public boolean search(int[] A, int target) {
120100
}
121101
}
122102
return false;
103+
} else if (target < A[0]) {
104+
if (target == A[len - 1]) {
105+
return true;
106+
} else if (target > A[len - 1]) {
107+
return false;
108+
} else if (target < A[len - 1]) {
109+
int start = watershedIndex + 1;
110+
int end = len - 2;
111+
int mid = (start + end) / 2;
112+
while (start <= end) {
113+
if (target > A[mid]) {
114+
start = mid + 1;
115+
mid = (start + end) / 2;
116+
} else if (target < A[mid]) {
117+
end = mid - 1;
118+
mid = (start + end) / 2;
119+
} else if (target == A[mid]) {
120+
return true;
121+
}
122+
}
123+
return false;
124+
}
123125
}
124126
}
127+
return false;
125128
}
126-
return false;
127129
}
128130

131+
public static class Solution2 {
132+
public boolean search(int[] nums, int target) {
133+
int start = 0;
134+
int end = nums.length - 1;
135+
136+
//check each num so we will check start == end
137+
//We always get a sorted part and a half part
138+
//we can check sorted part to decide where to go next
139+
while (start <= end) {
140+
int mid = start + (end - start) / 2;
141+
if (nums[mid] == target) {
142+
return true;
143+
}
144+
145+
//if left part is sorted
146+
if (nums[start] < nums[mid]) {
147+
if (target < nums[start] || target > nums[mid]) {
148+
//target is in rotated part
149+
start = mid + 1;
150+
} else {
151+
end = mid - 1;
152+
}
153+
} else if (nums[start] > nums[mid]) {
154+
//right part is rotated
155+
156+
//target is in rotated part
157+
if (target < nums[mid] || target > nums[end]) {
158+
end = mid - 1;
159+
} else {
160+
start = mid + 1;
161+
}
162+
} else {
163+
//duplicates, we know nums[mid] != target, so nums[start] != target
164+
//based on current information, we can only move left pointer to skip one cell
165+
//thus in the worst case, we would have target: 2, and array like 11111111, then
166+
//the running time would be O(n)
167+
start++;
168+
}
169+
}
170+
171+
return false;
172+
}
173+
}
129174
}

0 commit comments

Comments
 (0)