- 求一个数组序列的所有连续子序列(时间复杂度为O(N3))
private static void continSubString(int[] nums) {
List<List> result = new ArrayList<>();
for (int i = 0; i < nums.length; i++) {
for (int j = i; j < nums.length; j++) {
List<Integer> thisSubString = new ArrayList<>();
for (int k = i; k <= j; k++) {
thisSubString.add(nums[k]);
}
result.add(thisSubString);
}
}
System.out.println(Arrays.asList(result));
}
- 求一个数组中n个数的所有组合
public static void main(String[] args) {
int[] nums = new int[] {-2, 11, -4};
System.out.println(Arrays.asList(combine(nums, 2)));
}
private static List<List> combine(int[] nums, int count) {
List<List> res = new ArrayList<>();
List<Integer> thisCombine = new ArrayList<>();
combineHelper(nums, count, 0, thisCombine, res);
return res;
}
private static void combineHelper(int[] nums, int count, int pos, List<Integer> thisCombine, List<List> res) {
if (count == 0) {
ArrayList<Integer> tmp = new ArrayList<>(thisCombine);
res.add(tmp);
return;
}
for (int i = pos; i < nums.length; i++) {
thisCombine.add(nums[i]);
combineHelper(nums, count - 1, i + 1, thisCombine, res);
thisCombine.remove(thisCombine.size() - 1);
}
}
- 求一个数组的所有组合
将上面的程序main函数体改为
for (int i = 1; i <= nums.length; i++) {
System.out.println(Arrays.asList(combine(nums, i)));
}
4.1. 分治法求最大连续子序列和(O(NlogN))(为方便起见,若序列所有数均为负数,则最大子序列和为0,下同)
public static void main(String[] args) {
int[] nums = new int[] {4, -3, 5, -2, -1, 2, 6, -2};
System.out.println(maxSubSum(nums));
}
public static int maxSubSum(int[] nums) {
return maxSumRec(nums, 0, nums.length - 1);
}
private static int maxSumRec(int[] nums, int left, int right) {
if (left >= right) {
if (nums[left] > 0) {
return nums[left];
}
else {
return 0;
}
}
int center = (left + right) / 2;
int maxLeftSum = maxSumRec(nums, left, center);
int maxRightSum = maxSumRec(nums, center + 1, right);
int maxLeftBorderSum = 0;
int leftBorderSum = 0;
for (int i = center; i >= left; i--) {
leftBorderSum += nums[i];
if (leftBorderSum > maxLeftBorderSum) {
maxLeftBorderSum = leftBorderSum;
}
}
int maxRightBorderSum = 0;
int rightBorderSum = 0;
for (int i = center + 1; i <= right; i++) {
rightBorderSum += nums[i];
if (rightBorderSum > maxRightBorderSum) {
maxRightBorderSum = rightBorderSum;
}
}
return Math.max(Math.max(maxLeftSum, maxRightSum), maxLeftBorderSum + maxRightBorderSum);
}
4.2. 线性时间求最大连续子序列和(O(N))
public static int maxSubSum(int[] nums) {
int maxSum = 0;
int thisSum = 0;
for (int j = 0; j < nums.length; j++) {
thisSum += nums[j];
if (thisSum > maxSum) {
maxSum = thisSum;
} else if (thisSum < 0) {
thisSum = 0;
}
}
return maxSum;
}