LeetCode018 4Sum

详细见:leetcode.com/problems/4sum/


Java Solution: github

package leetcode;

import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

public class P018_4SumEqualsTarget {
	public static void main(String[] args) {
//		System.out.println(new Solution3().threeSum(new int[] {-4, -1, -1, 0, 1, 2}, -1, 0));
//		System.out.println(new Solution3().threeSum(new int[] {-2, 0, 0, 2, 2}, -1, 0));
		System.out.println(new Solution3().fourSum(new int[] {1, 0, -1, 0, -2, 2}, 0));
		System.out.println(new Solution3().fourSum(new int[] {-2, 2, 2, 2, 2, 2}, 4));
		System.out.println(new Solution3().fourSum(new int[] {2, 2, 2, 2, 2, 2, 4, 0}, 8));
//		Node node = new Node(4, 3, 2, 1);
//		Set<Node> set = new HashSet<Node>();
//		set.add(node);
//		node = new Node(4, 3, 1, 2);
//		set.add(node);
//		System.out.println(set.size());
	}
	/*
	 * 	106 ms
	 * 	6.18%
	 * 	O(N^3)
	 */
	static class Solution1 {
	    public List<List<Integer>> fourSum(int[] nums, int target) {
	        List<List<Integer>> ans = new LinkedList<List<Integer>>();
	        if (nums == null || nums.length < 4)
	        	return ans;
	        Arrays.sort(nums);
	        for (int i = 0; i != nums.length; i ++) {
	        	if (i != 0 && nums[i] == nums[i - 1])
	        		continue;
	        	List<List<Integer>> temp = threeSum(nums, i, target - nums[i]);
	        	Iterator<List<Integer>> it = temp.iterator();
	        	while (it.hasNext()) {
	        		List<Integer> list = it.next();
	        		list.add(nums[i]);
	        		ans.add(list);
	        	}
	        }
	        return ans;
	    }
	    List<List<Integer>> threeSum(int[] nums, int bomb, int target) {
	    	List<List<Integer>> ans = new LinkedList<List<Integer>>();
	    	int i = 0, j = 0, k = 0;
	    	for (i = bomb + 1; i != nums.length; i ++) {
	    		if (i != 0 && nums[i] == nums[i - 1] && (i != bomb + 1))	continue;
	    		j = i + 1;  k = nums.length - 1;
	    		while (j < k) {
	    			int sum = nums[i] + nums[j] + nums[k];
	    			if (sum == target) {
	    				List<Integer> list = new LinkedList<Integer>();
	    				list.add(nums[i]);   list.add(nums[j]);   list.add(nums[k]);
	    				ans.add(list);
	    				do {
	    					j ++;
	    				} while (j != nums.length && nums[j] == nums[j - 1]);
	    				do {
	    					k --;
	    				} while (k != -1 && nums[k] == nums[k + 1]);
	    			} else if (sum > target) {
	    				do {
	    					k --;
	    				} while (k != -1 && nums[k] == nums[k + 1]);
	    			} else {
	    				do {
	    					j ++;
	    				} while (j != nums.length && nums[j] == nums[j - 1]);
	    			}
	    		}
	    	}
	    	return ans;
	    }
	}
	/*
	 * 	87 ms
	 * 	11.81%
	 * 	O(N^3)
	 */
	static class Solution2 {
        List<List<Integer>> ans = new LinkedList<List<Integer>>();
	    public List<List<Integer>> fourSum(int[] nums, int target) {
	        if (nums == null || nums.length < 4)
	        	return ans;
	        Arrays.sort(nums);
	        for (int i = 0; i != nums.length; i ++) {
	        	if (i != 0 && nums[i] == nums[i - 1])
	        		continue;
	        	threeSum(nums, i, target - nums[i]);
	        }
	        return ans;
	    }
	    void threeSum(int[] nums, int bomb, int target) {
	    	int i = 0, j = 0, k = 0;
	    	for (i = bomb + 1; i != nums.length; i ++) {
	    		if (i != 0 && nums[i] == nums[i - 1] && (i != bomb + 1))	continue;
	    		j = i + 1;  k = nums.length - 1;
	    		while (j < k) {
	    			int sum = nums[i] + nums[j] + nums[k];
	    			if (sum == target) {
	    				List<Integer> list = new LinkedList<Integer>();
	    				list.add(nums[i]);   list.add(nums[j]);
	    				list.add(nums[k]);   list.add(nums[bomb]);
	    				ans.add(list);
	    				do {
	    					j ++;
	    				} while (j != nums.length && nums[j] == nums[j - 1]);
	    				do {
	    					k --;
	    				} while (k != -1 && nums[k] == nums[k + 1]);
	    			} else if (sum > target) {
	    				do {
	    					k --;
	    				} while (k != -1 && nums[k] == nums[k + 1]);
	    			} else {
	    				do {
	    					j ++;
	    				} while (j != nums.length && nums[j] == nums[j - 1]);
	    			}
	    		}
	    	}
	    }
	}
	/*
	 * 	采用HashMap的方法来进行计算
	 * 	光荣TLE
	 */
	static class Solution3 {
	    public List<List<Integer>> fourSum(int[] nums, int target) {
	    	List<List<Integer>> ans = new LinkedList<List<Integer>>();
	    	if (nums == null || nums.length < 4)
	    		return ans;
	    	HashMap<Integer, HashSet<Node>> map = new HashMap<Integer, HashSet<Node>>();
	    	HashSet<Node> ansset = new HashSet<Node>();
	    	HashMap<Integer, Integer> nums_map = new HashMap<Integer, Integer>();
	    	for (int i = 0; i != nums.length; i ++) {
	    		if (nums_map.containsKey(nums[i]))
	    			nums_map.put(nums[i], nums_map.get(nums[i]) + 1);
	    		else
	    			nums_map.put(nums[i], 1);
	    		for (int j = i + 1; j != nums.length; j ++) {
	    			int sum = nums[i] + nums[j];
	    			if (map.containsKey(sum)) {
	    				map.get(sum).add(new Node(nums[i], nums[j]));
	    			} else {
	    				HashSet<Node> set = new HashSet<Node>();
	    				set.add(new Node(nums[i], nums[j]));
	    				map.put(sum, set);
	    			}
	    		}
	    	}
	    	for (int k : map.keySet()) {
	    		if (map.containsKey(target - k)) {
	    			HashSet<Node> set1 = map.get(k);
	    			HashSet<Node> set2 = map.get(target - k);
	    			for (Node node1 : set1) {
	    				for (Node node2 : set2) {
	    					nums_map.put(node1.a, nums_map.get(node1.a) - 1);
	    					nums_map.put(node1.b, nums_map.get(node1.b) - 1);
	    					nums_map.put(node2.a, nums_map.get(node2.a) - 1);
	    					nums_map.put(node2.b, nums_map.get(node2.b) - 1);
	    					if (nums_map.get(node1.a) > -1 && nums_map.get(node1.b) > -1 &&
	    							nums_map.get(node2.a) > -1 && nums_map.get(node2.b) > -1) {
	    						ansset.add(new Node(node1.a, node1.b, node2.a, node2.b));
	    					}
	    					nums_map.put(node1.a, nums_map.get(node1.a) + 1);
	    					nums_map.put(node1.b, nums_map.get(node1.b) + 1);
	    					nums_map.put(node2.a, nums_map.get(node2.a) + 1);
	    					nums_map.put(node2.b, nums_map.get(node2.b) + 1);
	    				}
	    			}
	    		}
	    	}
	    	for (Node node : ansset) {
	    		List<Integer> list = new LinkedList<Integer>();
	    		list.add(node.a);
	    		list.add(node.b);
	    		list.add(node.c);
	    		list.add(node.d);
	    		ans.add(list);
	    	}
	    	return ans;
	    }
	}
	 static class Node {
	    	int a, b, c, d;
	    	public Node (int a, int b) {
	    		this.a = a;
	    		this.b = b;
	    		this.c = Integer.MAX_VALUE;
	    		this.d = Integer.MAX_VALUE;
	    	}
	    	public Node (int a, int b, int c, int d) {
	    		int temp = 0;
	    		if (a > b) {
	    			temp = a;
	    			a = b;
	    			b = temp;
	    		}
	    		if (c > d) {
	    			temp = c;
	    			c = d;
	    			d = temp;
	    		}
	    		this.a = Math.min(a, c);
	    		this.d = Math.max(b, d);
	    		c = this.a == a ? c : a;
	    		b = this.d == d ? b : d;
	    		if (b < c) {
	    			this.b = b;
	    			this.c = c;
	    		} else {
	    			this.b = c;
	    			this.c = b;
	    		}
	    	}
			@Override
			public boolean equals(Object obj) {
				if (obj instanceof Node) {
					Node o = (Node) obj;
					return this.a == o.a && this.b == o.b && this.c == o.c && this.d == o.d;
				} else {
					return false;
				}
			}
	    	@Override
	    	public int hashCode() {
	    		return a * 11 + b * 22 + c * 33 + d * 44;
	    	}
	    }
}

C Solution: github

/*
    url: leetcode.com/problems/4sum/
    36ms 45.28%
*/

#include <stdio.h>
#include <stdlib.h>

//[l, r]
int partition(int* a, int l, int r) {
    int t = *(a + l);
    while (l < r) {
        while (l < r && *(a + r) >= t) r --;
        *(a + l) = *(a + r);
        while (l < r && *(a + l) <= t) l ++;
        *(a + r) = *(a + l);
    }
    *(a + l) = t;
    return l;
}

//[l, r)
void quick_sort(int* a, int l, int r) {
    int p = 0;
    if (l < r) {
        p = partition(a, l, r - 1);
        quick_sort(a, l, p);
        quick_sort(a, p + 1, r);
    }
}

struct list {
    int a[4];
    struct list *next;
};

void free_list(struct list * head) {
    struct list * next = head;
    while (next != NULL) {
        head = next->next;
        free(next);
        next = head;
    }
}

int** fourSum(int* nums, int numsSize, int target, int* returnSize) {
    int ** answer = NULL;
    struct list * head = NULL, * next = NULL, * temp = NULL;
    int i = 0, j = 0, l = 0, r = 0, sum = 0, count = 0;
    int * answer_temp = NULL;
    quick_sort(nums, 0, numsSize);
    for (i = 0; i < numsSize; i ++) {
        if (i != 0 && *(nums + i - 1) == *(nums + i))
            continue;
        for (j = i + 1; j < numsSize; j ++) {
            if (j != i + 1 && *(nums + j - 1) == *(nums + j))
                continue;
            l = j + 1;
            r = numsSize - 1;
            while (l < r) {
                sum = *(nums + i) + *(nums + j) + *(nums + l) + *(nums + r);
                if (sum == target) {
                    temp = (struct list *) malloc(sizeof(struct list));
                    temp->next = NULL;
                    temp->a[0] = *(nums + i);
                    temp->a[1] = *(nums + j);
                    temp->a[2] = *(nums + l);
                    temp->a[3] = *(nums + r);
                    if (NULL == head) {
                        head = temp;
                        next = temp;
                    } else {
                        next->next = temp;
                        next = temp;
                    }
                    count ++;
                    do {
                        l ++;
                    } while (l < r && nums[l - 1] == nums[l]);
                    do {
                        r --;
                    } while (l < r && nums[r + 1] == nums[r]);
                } else if (sum > target) {
                    do {
                        r --;
                    } while (l < r && nums[r + 1] == nums[r]);
                } else {
                    do {
                        l ++;
                    } while (l < r && nums[l - 1] == nums[l]);
                }
            }
        }
    }
    answer = (int **) malloc(sizeof(int *) * count);
    next = head;
    for (i = 0; i < count; i ++) {
        answer_temp = (int *) malloc(sizeof(int) * 4);
        answer_temp[0] = next->a[0];
        answer_temp[1] = next->a[1];
        answer_temp[2] = next->a[2];
        answer_temp[3] = next->a[3];
        *(answer + i) = answer_temp;
        next = next->next;
    }
    free_list(head);
    *(returnSize) = count;
    return answer;
}

int main() {
    int nums[] = {-1,0,1,2,-1,-4};
    //int nums[] = {1, 1, 1, 1, 1, 1};
    int numsSize = 6;
    int target = -1;
    int returnSize[] = {0};
    int ** a = fourSum(nums, numsSize, target, returnSize);
    int i = 0;
    printf("answer length is %d\r\n", *(returnSize));
    for (i = 0; i < *(returnSize); i ++)
        free(*(a + i));
    free(a);
    return 0;
}

Python Solution: github

#coding=utf-8

'''
    url: leetcode.com/problems/4sum/
    @author:     zxwtry
    @email:      zxwtry@qq.com
    @date:       2017年3月28日
    @details:    Solution1: TLE
    @details:    Solution2: 745ms 53.60%
'''

class Solution1(object):
    def search(self, a, n, s, t, i, I, p, pi):
        if pi == 4:
            #Python2 LeetCode Judge is Python2
            #if s == t: a.append(p[:])
            #Python3
            if s == t: a.append(p.copy())
            return
        for j in range(i, I):
            if j != i and n[j - 1] == n[j]: continue
            p[pi] = n[j]
            self.search(a, n, s + n[j], t, j + 1, I, p, pi + 1)
        
    def fourSum(self, n, t):
        """
        :type n: List[int]
        :type t: int
        :rtype: List[List[int]]
        """
        a = []
        nn = 0 if n == None else len(n)
        if nn == 0: return a
        n.sort(key=None, reverse=False)
        self.search(a, n, 0, t, 0, nn, [0] * 4, 0)
        return a
    
class Solution2(object):
    def fourSum(self, n, target):
        a = []
        nn = 0 if n == None else len(n)
        if nn == 0: return a
        n.sort(key=None, reverse=False)
        for i in range(nn):
            if i != 0 and n[i - 1] == n[i]: continue
            for j in range(i + 1, nn):
                if j != i + 1 and n[j - 1] == n[j]: continue
                l, r, t = j + 1, nn - 1, target-n[i]-n[j]
                while l < r:
                    s = n[l] + n[r]
                    if s == t:
                        a.append([n[i], n[j], n[l], n[r]])
                        while True:
                            l += 1
                            if l >= r or n[l-1] != n[l]: break
                        while True:
                            r -= 1
                            if l >= r or n[r+1] != n[r]: break
                    elif s < t:
                        l += 1
                    else:
                        r -= 1
        return a

if __name__ == "__main__":
    n = [1,0,-1,0,-2,2]
    t = 0
    print(Solution2().fourSum(n, t))
        







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值