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) {
|
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;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user