一、LeetCode——求和问题

8 篇文章 0 订阅

求和问题笔记,后续会补充=-=

求和相关问题

最简单的两数求和==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;
		
        
    }

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值