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) {
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;
}
}
}