Skip to content

Commit 06190f2

Browse files
committed
auto commit
1 parent 03bb846 commit 06190f2

File tree

1 file changed

+57
-21
lines changed

1 file changed

+57
-21
lines changed

notes/算法.md

Lines changed: 57 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -104,17 +104,21 @@ public class ThreeSumSlow implements ThreeSum {
104104
public int count(int[] nums) {
105105
int N = nums.length;
106106
int cnt = 0;
107-
for (int i = 0; i < N; i++)
108-
for (int j = i + 1; j < N; j++)
109-
for (int k = j + 1; k < N; k++)
110-
if (nums[i] + nums[j] + nums[k] == 0)
107+
for (int i = 0; i < N; i++) {
108+
for (int j = i + 1; j < N; j++) {
109+
for (int k = j + 1; k < N; k++) {
110+
if (nums[i] + nums[j] + nums[k] == 0) {
111111
cnt++;
112+
}
113+
}
114+
}
115+
}
112116
return cnt;
113117
}
114118
}
115119
```
116120

117-
### 2. ThreeSumFast
121+
### 2. ThreeSumBinarySearch
118122

119123
通过将数组先排序,对两个元素求和,并用二分查找方法查找是否存在该和的相反数,如果存在,就说明存在三元组的和为 0。
120124

@@ -123,42 +127,83 @@ public class ThreeSumSlow implements ThreeSum {
123127
该方法可以将 ThreeSum 算法增长数量级降低为 O(N<sup>2</sup>logN)。
124128

125129
```java
126-
public class ThreeSumFast {
127-
public static int count(int[] nums) {
130+
public class ThreeSumBinarySearch implements ThreeSum {
131+
132+
@Override
133+
public int count(int[] nums) {
128134
Arrays.sort(nums);
129135
int N = nums.length;
130136
int cnt = 0;
131-
for (int i = 0; i < N; i++)
137+
for (int i = 0; i < N; i++) {
132138
for (int j = i + 1; j < N; j++) {
133139
int target = -nums[i] - nums[j];
134140
int index = BinarySearch.search(nums, target);
135141
// 应该注意这里的下标必须大于 j,否则会重复统计。
136-
if (index > j)
142+
if (index > j) {
137143
cnt++;
144+
}
138145
}
146+
}
139147
return cnt;
140148
}
141149
}
142150
```
143151

144152
```java
145153
public class BinarySearch {
154+
146155
public static int search(int[] nums, int target) {
147156
int l = 0, h = nums.length - 1;
148157
while (l <= h) {
149158
int m = l + (h - l) / 2;
150-
if (target == nums[m])
159+
if (target == nums[m]) {
151160
return m;
152-
else if (target > nums[m])
161+
} else if (target > nums[m]) {
153162
l = m + 1;
154-
else
163+
} else {
155164
h = m - 1;
165+
}
156166
}
157167
return -1;
158168
}
159169
}
160170
```
161171

172+
### 3. ThreeSumTwoPointer
173+
174+
更有效的方法是先将数组排序,然后使用双指针进行查找,时间复杂度为 O(N<sup>2</sup>)。
175+
176+
```java
177+
public class ThreeSumTwoPointer implements ThreeSum {
178+
179+
@Override
180+
public int count(int[] nums) {
181+
int N = nums.length;
182+
int cnt = 0;
183+
Arrays.sort(nums);
184+
for (int i = 0; i < N - 2; i++) {
185+
int l = i + 1, h = N - 1, target = -nums[i];
186+
if (i > 0 && nums[i] == nums[i - 1]) continue;
187+
while (l < h) {
188+
int sum = nums[l] + nums[h];
189+
if (sum == target) {
190+
cnt++;
191+
while (l < h && nums[l] == nums[l + 1]) l++;
192+
while (l < h && nums[h] == nums[h - 1]) h--;
193+
l++;
194+
h--;
195+
} else if (sum < target) {
196+
l++;
197+
} else {
198+
h--;
199+
}
200+
}
201+
}
202+
return cnt;
203+
}
204+
}
205+
```
206+
162207
## 倍率实验
163208

164209
如果 T(N) \~ aN<sup>b</sup>logN,那么 T(2N)/T(N) \~ 2<sup>b</sup>。
@@ -180,29 +225,20 @@ public class BinarySearch {
180225
public class RatioTest {
181226

182227
public static void main(String[] args) {
183-
184228
int N = 500;
185229
int loopTimes = 7;
186230
double preTime = -1;
187-
188231
while (loopTimes-- > 0) {
189-
190232
int[] nums = new int[N];
191-
192233
StopWatch.start();
193-
194234
ThreeSum threeSum = new ThreeSumSlow();
195-
196235
int cnt = threeSum.count(nums);
197236
System.out.println(cnt);
198-
199237
double elapsedTime = StopWatch.elapsedTime();
200238
double ratio = preTime == -1 ? 0 : elapsedTime / preTime;
201239
System.out.println(N + " " + elapsedTime + " " + ratio);
202-
203240
preTime = elapsedTime;
204241
N *= 2;
205-
206242
}
207243
}
208244
}

0 commit comments

Comments
 (0)