auto commit
This commit is contained in:
parent
03bb846a22
commit
06190f2f19
78
notes/算法.md
78
notes/算法.md
|
@ -104,17 +104,21 @@ public class ThreeSumSlow implements ThreeSum {
|
|||
public int count(int[] nums) {
|
||||
int N = nums.length;
|
||||
int cnt = 0;
|
||||
for (int i = 0; i < N; i++)
|
||||
for (int j = i + 1; j < N; j++)
|
||||
for (int k = j + 1; k < N; k++)
|
||||
if (nums[i] + nums[j] + nums[k] == 0)
|
||||
for (int i = 0; i < N; i++) {
|
||||
for (int j = i + 1; j < N; j++) {
|
||||
for (int k = j + 1; k < N; k++) {
|
||||
if (nums[i] + nums[j] + nums[k] == 0) {
|
||||
cnt++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return cnt;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 2. ThreeSumFast
|
||||
### 2. ThreeSumBinarySearch
|
||||
|
||||
通过将数组先排序,对两个元素求和,并用二分查找方法查找是否存在该和的相反数,如果存在,就说明存在三元组的和为 0。
|
||||
|
||||
|
@ -123,19 +127,23 @@ public class ThreeSumSlow implements ThreeSum {
|
|||
该方法可以将 ThreeSum 算法增长数量级降低为 O(N<sup>2</sup>logN)。
|
||||
|
||||
```java
|
||||
public class ThreeSumFast {
|
||||
public static int count(int[] nums) {
|
||||
public class ThreeSumBinarySearch implements ThreeSum {
|
||||
|
||||
@Override
|
||||
public int count(int[] nums) {
|
||||
Arrays.sort(nums);
|
||||
int N = nums.length;
|
||||
int cnt = 0;
|
||||
for (int i = 0; i < N; i++)
|
||||
for (int i = 0; i < N; i++) {
|
||||
for (int j = i + 1; j < N; j++) {
|
||||
int target = -nums[i] - nums[j];
|
||||
int index = BinarySearch.search(nums, target);
|
||||
// 应该注意这里的下标必须大于 j,否则会重复统计。
|
||||
if (index > j)
|
||||
if (index > j) {
|
||||
cnt++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return cnt;
|
||||
}
|
||||
}
|
||||
|
@ -143,22 +151,59 @@ public class ThreeSumFast {
|
|||
|
||||
```java
|
||||
public class BinarySearch {
|
||||
|
||||
public static int search(int[] nums, int target) {
|
||||
int l = 0, h = nums.length - 1;
|
||||
while (l <= h) {
|
||||
int m = l + (h - l) / 2;
|
||||
if (target == nums[m])
|
||||
if (target == nums[m]) {
|
||||
return m;
|
||||
else if (target > nums[m])
|
||||
} else if (target > nums[m]) {
|
||||
l = m + 1;
|
||||
else
|
||||
} else {
|
||||
h = m - 1;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 3. ThreeSumTwoPointer
|
||||
|
||||
更有效的方法是先将数组排序,然后使用双指针进行查找,时间复杂度为 O(N<sup>2</sup>)。
|
||||
|
||||
```java
|
||||
public class ThreeSumTwoPointer implements ThreeSum {
|
||||
|
||||
@Override
|
||||
public int count(int[] nums) {
|
||||
int N = nums.length;
|
||||
int cnt = 0;
|
||||
Arrays.sort(nums);
|
||||
for (int i = 0; i < N - 2; i++) {
|
||||
int l = i + 1, h = N - 1, target = -nums[i];
|
||||
if (i > 0 && nums[i] == nums[i - 1]) continue;
|
||||
while (l < h) {
|
||||
int sum = nums[l] + nums[h];
|
||||
if (sum == target) {
|
||||
cnt++;
|
||||
while (l < h && nums[l] == nums[l + 1]) l++;
|
||||
while (l < h && nums[h] == nums[h - 1]) h--;
|
||||
l++;
|
||||
h--;
|
||||
} else if (sum < target) {
|
||||
l++;
|
||||
} else {
|
||||
h--;
|
||||
}
|
||||
}
|
||||
}
|
||||
return cnt;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 倍率实验
|
||||
|
||||
如果 T(N) \~ aN<sup>b</sup>logN,那么 T(2N)/T(N) \~ 2<sup>b</sup>。
|
||||
|
@ -180,29 +225,20 @@ public class BinarySearch {
|
|||
public class RatioTest {
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
int N = 500;
|
||||
int loopTimes = 7;
|
||||
double preTime = -1;
|
||||
|
||||
while (loopTimes-- > 0) {
|
||||
|
||||
int[] nums = new int[N];
|
||||
|
||||
StopWatch.start();
|
||||
|
||||
ThreeSum threeSum = new ThreeSumSlow();
|
||||
|
||||
int cnt = threeSum.count(nums);
|
||||
System.out.println(cnt);
|
||||
|
||||
double elapsedTime = StopWatch.elapsedTime();
|
||||
double ratio = preTime == -1 ? 0 : elapsedTime / preTime;
|
||||
System.out.println(N + " " + elapsedTime + " " + ratio);
|
||||
|
||||
preTime = elapsedTime;
|
||||
N *= 2;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user