[leetCode]剑指 Offer 57. 和为s的两个数字、II. 和为s的连续正数序列
解法 双指针
由于数组是递增排序的所以可以设置两个指针,一个指向头部,一个指向尾部。两指针所指元素相加,若大于目标值则跳转尾部指针向前移动。若小于目标值则调整头部指针向后移动。
class Solution {
public int[] twoSum(int[] nums, int target) {
if (nums == null || nums.length == 0)
return new int[]{};
// 向前移动的指针
int ahead = nums.length - 1;
// 向后移动的指针
int behind = 0;
int[] ans = new int[2];
while (ahead > behind) {
int sum = nums[ahead] + nums[behind];
if (sum == target) {
ans[0] = nums[behind];
ans[1] = nums[ahead];
return ans;
} else if (sum > target) {
--ahead;
} else {
++behind;
}
}
return new int[]{};
}
}
剑指 Offer 57 - II. 和为s的连续正数序列
解法
与上面解法类似,可以使用一个指针small先指向1,一个指针big指向2。将small~big之间的数字相加,如果其和sum等于目标值则将此序列添加到结果中,如果sum小于目标值则调整small指针,使其增大。目标和大于目标值则调整big指针使其减小。由于序列至少要有两个数字所以增加small到(target + 1)/2 为止。
class Solution {
public int[][] findContinuousSequence(int target) {
if (target < 3) return new int[][]{};
int small = 1;
int big = 2;
int middle = (target + 1) >> 1;
int sum = small + big;
List<int[]> ans = new LinkedList<>();
while (small < middle) {
if (sum == target)
addOneAns(ans, small, big);
while (sum > target && small < middle) {
sum -= small;
++small;
if (sum == target)
addOneAns(ans, small, big);
}
++big;
sum += big;
}
return ans.toArray(new int[ans.size()][]);
}
private void addOneAns(List<int[]> ans, int small, int big) {
int[] row = new int[big - small + 1];
for (int i = small; i <= big; ++i) {
row[i - small] = i;
}
ans.add(row);
}
}