auto commit

This commit is contained in:
CyC2018 2018-08-28 22:55:26 +08:00
parent 03bb846a22
commit 06190f2f19

View File

@ -104,17 +104,21 @@ public class ThreeSumSlow implements ThreeSum {
public int count(int[] nums) { public int count(int[] nums) {
int N = nums.length; int N = nums.length;
int cnt = 0; 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++) for (int j = i + 1; j < N; j++) {
for (int k = j + 1; k < N; k++) for (int k = j + 1; k < N; k++) {
if (nums[i] + nums[j] + nums[k] == 0) if (nums[i] + nums[j] + nums[k] == 0) {
cnt++; cnt++;
}
}
}
}
return cnt; return cnt;
} }
} }
``` ```
### 2. ThreeSumFast ### 2. ThreeSumBinarySearch
通过将数组先排序,对两个元素求和,并用二分查找方法查找是否存在该和的相反数,如果存在,就说明存在三元组的和为 0。 通过将数组先排序,对两个元素求和,并用二分查找方法查找是否存在该和的相反数,如果存在,就说明存在三元组的和为 0。
@ -123,19 +127,23 @@ public class ThreeSumSlow implements ThreeSum {
该方法可以将 ThreeSum 算法增长数量级降低为 O(N<sup>2</sup>logN)。 该方法可以将 ThreeSum 算法增长数量级降低为 O(N<sup>2</sup>logN)。
```java ```java
public class ThreeSumFast { public class ThreeSumBinarySearch implements ThreeSum {
public static int count(int[] nums) {
@Override
public int count(int[] nums) {
Arrays.sort(nums); Arrays.sort(nums);
int N = nums.length; int N = nums.length;
int cnt = 0; 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++) { for (int j = i + 1; j < N; j++) {
int target = -nums[i] - nums[j]; int target = -nums[i] - nums[j];
int index = BinarySearch.search(nums, target); int index = BinarySearch.search(nums, target);
// 应该注意这里的下标必须大于 j否则会重复统计。 // 应该注意这里的下标必须大于 j否则会重复统计。
if (index > j) if (index > j) {
cnt++; cnt++;
}
} }
}
return cnt; return cnt;
} }
} }
@ -143,22 +151,59 @@ public class ThreeSumFast {
```java ```java
public class BinarySearch { public class BinarySearch {
public static int search(int[] nums, int target) { public static int search(int[] nums, int target) {
int l = 0, h = nums.length - 1; int l = 0, h = nums.length - 1;
while (l <= h) { while (l <= h) {
int m = l + (h - l) / 2; int m = l + (h - l) / 2;
if (target == nums[m]) if (target == nums[m]) {
return m; return m;
else if (target > nums[m]) } else if (target > nums[m]) {
l = m + 1; l = m + 1;
else } else {
h = m - 1; h = m - 1;
}
} }
return -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> 如果 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 class RatioTest {
public static void main(String[] args) { public static void main(String[] args) {
int N = 500; int N = 500;
int loopTimes = 7; int loopTimes = 7;
double preTime = -1; double preTime = -1;
while (loopTimes-- > 0) { while (loopTimes-- > 0) {
int[] nums = new int[N]; int[] nums = new int[N];
StopWatch.start(); StopWatch.start();
ThreeSum threeSum = new ThreeSumSlow(); ThreeSum threeSum = new ThreeSumSlow();
int cnt = threeSum.count(nums); int cnt = threeSum.count(nums);
System.out.println(cnt); System.out.println(cnt);
double elapsedTime = StopWatch.elapsedTime(); double elapsedTime = StopWatch.elapsedTime();
double ratio = preTime == -1 ? 0 : elapsedTime / preTime; double ratio = preTime == -1 ? 0 : elapsedTime / preTime;
System.out.println(N + " " + elapsedTime + " " + ratio); System.out.println(N + " " + elapsedTime + " " + ratio);
preTime = elapsedTime; preTime = elapsedTime;
N *= 2; N *= 2;
} }
} }
} }