leetcode: 4Sum

来源:互联网 发布:三日月宗近锻刀数据 编辑:程序博客网 时间:2024/05/21 01:43
思路:现将给定数组中的元素两两求和,并用Map存储,key是和值,value是求和的两元素值及其下标。然后遍历key集合寻找其中和为0的两个key值,并排除重复元素,即可确定

代码:

public class Solution {    public List<List<Integer>> fourSum(int[] num, int target) {List<List<Integer>> res = new ArrayList<List<Integer>>();Map<Integer, List<Integer[]>> sum_list = new HashMap<Integer, List<Integer[]>>();  //用于存放两两元素和,及这两个元素的值和索引int len = num.length;Arrays.sort(num);for(int i=0; i<len-1; i++) {for(int j=i+1; j<len; j++) {Integer k = num[i] + num[j];Integer[] it = new Integer[] {num[i], i, num[j], j};// 判断此key是否已经存在于sum_list,如果没有,则新建一个List,用于存放元素值及其对应的下标if(!sum_list.containsKey(k)) {sum_list.put(k, new ArrayList<Integer[]>());}sum_list.get(k).add(it);}}// 取出所有key到一个Set中,遍历Set(Iterator), 然后判断是否存在两个key之和为0的(下面两种取key集合的方式都可以)Set<Integer> keys = sum_list.keySet();// Integer[] keys = sum_list.keySet().toArray(new Integer[sum_list.size()]);for(Integer k: keys) {if(sum_list.containsKey(target-k)) {// 分别取出k和target-k对应的ListList<Integer[]> firstList = sum_list.get(k);List<Integer[]> secondList = sum_list.get(target-k);// 分别遍历firstList和secondList的列表项,避免相同位置的相同值被重复使用(确保每个值只被用一次)for(int i=0; i<firstList.size(); i++) {    Integer[] firstItem = firstList.get(i);for(int j=0; j<secondList.size(); j++) {Integer[] secondItem = secondList.get(j);if(firstItem[1]!=secondItem[1] && firstItem[1]!=secondItem[3] && firstItem[3]!=secondItem[1] && firstItem[3]!=secondItem[3]) {List l = Arrays.asList(firstItem[0], firstItem[2], secondItem[0], secondItem[2]);Collections.sort(l);if(!res.contains(l))    res.add(l);}}}}}return res;}}


0 0