两数之和
解法一:
暴力枚举【时间复杂度O(N^2), 空间复杂度O(1)】
解法二:
排序+双指针【时间复杂度O(NlogN),空间复杂度O(N)】
class Solution {
public int[] twoSum(int[] nums, int target) {
Data[] list = new Data[nums.length];
for (int i = 0; i < nums.length; i++) {
list[i] = new Data(i, nums[i]);
}
Arrays.sort(list);
int[] ans = new int[2];
int front = 0, back = nums.length - 1;
int sum;
while(front < back) {
sum = list[front].value + list[back].value;
if (sum > target) {
back--;
} else if (sum < target) {
front++;
} else {
ans[0] = list[front].index;
ans[1] = list[back].index;
return ans;
}
}
return ans;
}
}
class Data implements Comparable<Data> {
int index;
int value;
public Data(int index, int value) {
this.index = index;
this.value = value;
}
//定义排序规则:根据value按从小到大排序
public int compareTo(Data x) {
return this.value - x.value;
}
}
解法三:
官方题解:时间复杂度:O(N),空间复杂度:O(N)
class Solution {
public int[] twoSum(int[] nums, int target) {
Map<Integer, Integer> hashtable = new HashMap<Integer, Integer>();
for (int i = 0; i < nums.length; ++i) {
if (hashtable.containsKey(target - nums[i])) {
return new int[]{hashtable.get(target - nums[i]), i};
}
hashtable.put(nums[i], i);
}
return new int[0];
}
}
三数之和
排序 + 双指针
【时间复杂度:O(N^2),空间复杂度:O(log N) 】
class Solution {
public List<List<Integer>> threeSum(int[] nums) {
List<List<Integer>> ans = new ArrayList<>();
Arrays.sort(nums); //先排序
int sum;
/**
先固定一个数nums[k],然后双指针 i,j 分设在数组索引 (k, len(nums))两端,
通过双指针交替向中间移动,记录对于每个固定指针 k 的所有满足
nums[k] + nums[i] + nums[j] == 0 的 i,j 组合
*/
for (int k = 0; k < nums.length - 2; k++) { //答案要求3个数,故剩2个数就不用继续遍历下去
int i = k + 1, j = nums.length - 1;
if (nums[k] > 0) break; //因为已有序,故nums[k]都大于0后面就都不用找了
if (k > 0 && nums[k] == nums[k-1]) continue; //去重
while (i < j) {
sum = nums[k] + nums[i] + nums[j];
if (sum > 0) {
while (i < j && nums[j] == nums[--j]);
} else if (sum < 0) {
while (i < j && nums[i] == nums[++i]);
} else {
ans.add(new ArrayList<Integer>(Arrays.asList(nums[k], nums[i], nums[j])));
while (i < j && nums[i] == nums[++i]); //去重
while (i < j && nums[j] == nums[--j]); //去重
}
}
}
return ans;
}
}