求和问题笔记,后续会补充=-=
求和相关问题
最简单的两数求和==target问题
class Solution {
public int[] twoSum(int[] nums, int target) {
int length = nums.length;
for(int i = 0; i < length; i++){
for(int j = i + 1; j < length ; j++){
if( nums[i] + nums[j] == target ){
return new int[]{i,j};
}
}
}
return null;
}
}
优化后,只用循环一遍,耗时是上一个的1/10。利用hashmap的键值对找寻正确的结果
class Solution {
public int[] twoSum(int[] nums, int target) {
HashMap<Integer,Integer> _map = new HashMap<>();
for (int pos=0; pos<nums.length; pos++){
if (_map.containsKey(target-nums[pos])){
return new int[]{_map.get(target-nums[pos]),pos};
}
_map.put(nums[pos], pos);
}
return null;
}
}
进阶一点,三个数求和。一开始三重循环,但当一些复杂一点的计算就超时了,后来就用上一个学到的hashmap来做。添加的一些奇奇怪怪的判断是为了去重,使用set也是为了去重。
public List<List<Integer>> threeSum(int[] nums) {
HashMap<Integer, List<Integer>> map = null;
Arrays.sort(nums);
List<Integer> list = null;
Set<List<Integer>> set = new HashSet<List<Integer>>();
int length = nums.length;
int flag_j ,flag_i =0;
for (int i = 0; ; ) {
map = new HashMap();
flag_j =0;
for (int j = i+1; j < length; j++) {
if(nums[j]==nums[j-1]&&(j-1)!=i){
if(flag_j ==0){
flag_j=1;
}else{
continue;
}
}else{
flag_j = 0;
}
int key = 0-nums[i]-nums[j];
if (map.containsKey(nums[j])) {
list =new ArrayList<Integer>(map.get(nums[j]));
list.add(nums[j]);
set.add(list);
}
list =new ArrayList<Integer>();
list.add(nums[i]);
list.add(nums[j]);
map.put(key, list);
}
i++;
if(i >= length){
break;
}
if(nums[i]==nums[i-1]){
if(flag_i==0){
flag_i =1;
}else{
continue;
}
}else{
flag_i =0;
}
}
List<List<Integer>> answer = new ArrayList<List<Integer>>();
for (List<Integer> temp : set) {
answer.add(temp);
}
return answer;
}
别人写的,思想很简单,通过限定循环范围来降低复杂度,耗时为上一个的1/20
public List<List<Integer>> threeSum(int[] num) {
Arrays.sort(num);
List<List<Integer>> res = new LinkedList<>();
for (int i = 0; i < num.length-2; i++) {
if (i == 0 || (i > 0 && num[i] != num[i-1])) {
int lo = i+1, hi = num.length-1, sum = 0 - num[i];
while (lo < hi) {
if (num[lo] + num[hi] == sum) {
res.add(Arrays.asList(num[i], num[lo], num[hi]));
while (lo < hi && num[lo] == num[lo+1]) lo++;
while (lo < hi && num[hi] == num[hi-1]) hi--;
lo++; hi--;
} else if (num[lo] + num[hi] < sum) lo++;
else hi--;
}
}
}
return res;
}
再难一丢丢,四个数求和问题。这次依照三数求和限定范围来改写的
public List<List<Integer>> fourSum(int[] num, int target) {
Arrays.sort(num);
List<List<Integer>> res = new LinkedList<>();
for (int i = 0; i < num.length - 3; i++) {
if (i == 0 || (i > 0 && num[i] != num[i - 1])) {
for (int j = i + 1; j < num.length - 2; j++) {
if (j == i+1 || (j > i+1 && num[j] != num[j - 1])) {
int lo = j + 1, hi = num.length - 1, sum = target - num[i] - num[j];
while (lo < hi) {
if (num[lo] + num[hi] == sum) {
res.add(Arrays.asList(num[i], num[j] ,num[lo], num[hi]));
while (lo < hi && num[lo] == num[lo + 1])
lo++;
while (lo < hi && num[hi] == num[hi - 1])
hi--;
lo++;
hi--;
} else if (num[lo] + num[hi] < sum)
lo++;
else
hi--;
}
}
}
}
}
return res;
}