【leetcode with java】18 4Sum (On^2)

我看了几个人气比较高的博客,他们这个算法都没做到O(n^2),所以提前将我的解法贴出来分享,供大家参考(前面略过的题目近期都会补上的)。

【题目】:

Given an array S of n integers, are there elements a, b, c, and d in S such that a + b + c + d = target? Find all unique quadruplets in the array which gives the sum of target.

Note:
Elements in a quadruplet (a,b,c,d) must be in non-descending order. (ie, a ≤ b ≤ c ≤ d)
The solution set must not contain duplicate quadruplets.
    For example, given array S = {1 0 -1 0 -2 2}, and target = 0.

    A solution set is:
    (-1,  0, 0, 1)
    (-2, -1, 1, 2)
    (-2,  0, 0, 2)
Tags: Array Hash Table Two Pointers

【解析】 我写代码的时候把思路写在了代码注释里了,请直接往下看:

【上码】

import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.List;
import java.util.Vector;

/*
 * 参考:未参考他人算法
 * O(n^2)
 * 思路:先将每对数塞进一个Hashtable(以这对数的和为key,以一个包含所有和为key的数对的集合为value)。
 * 然后遍历该Hashtable,对于每个和为key的数对集合,在该Hashtable中get和为target-key的数对集合,
 * 如果get到的为空,则continue,如果get到的不为空,则将这两个数对和并为一个有序4元组,并查看是否之前该
 * 4元组是否已经出现过(用另一个Hastable<String,AnyType>:reappear来快速判断,该reappear的
 * key是用有序4元组的4个整数拼接而来的)。 如果该4元组为出现过,则将其加入到结果集合里。
 *
 */
public class Solution1 {
	public List<List<Integer>> fourSum(int[] num, int target) {
		List<List<Integer>> list = new ArrayList<List<Integer>>();
		if (num == null || num.length < 4)
			return list;
		int len = num.length;

		Hashtable<Integer,PairRecoder> prs = new Hashtable<Integer,PairRecoder>(len*len);
		for (int i = 0; i < len - 1; i++) {
			for (int j = i + 1; j < len; j++) {
				int sum = num[i]+num[j];
				PairRecoder pr = prs.get(num[i]+num[j]);
				if(pr == null)
					prs.put(sum, new PairRecoder(sum,i,j));
				else
					pr.pairs.add(new Pair(i,j));
			}
		}

		List<Four> fours = new ArrayList<Four>();
		Hashtable<String,Boolean> reappear = new  Hashtable<String,Boolean>();
		for(Enumeration<PairRecoder> e=prs.elements(); e.hasMoreElements(); ){
			PairRecoder pr1 = (PairRecoder)e.nextElement();
			PairRecoder pr2 = prs.get(target-pr1.v);
			if(pr2 == null)
				continue;
			for(int i=0;i<pr1.pairs.size();i++)
				for(int j=0;j<pr2.pairs.size();j++){
					Pair p1 = pr1.pairs.elementAt(i);
					Pair p2 = pr2.pairs.elementAt(j);
					if(p1.v1!=p2.v1 &&p1.v1!=p2.v2 && p1.v2!=p2.v1 && p1.v2!=p2.v2){
						Four of = new OrderedFour(num[p1.v1],num[p1.v2],num[p2.v1],num[p2.v2]);
						StringBuffer sb = new StringBuffer();
						sb.append(of.num.get(0));
						sb.append(of.num.get(1));
						sb.append(of.num.get(2));
						sb.append(of.num.get(3));
						if(!reappear.containsKey(sb.toString())){
							list.add(of.num);
							System.out.println("new:"+sb);
							reappear.put(sb.toString(),true);
						}
					}
				}
		}

		return list;
	}

	class Pair {
		int v1;
		int v2;
		Pair(int v1, int v2) {
			this.v1 = v1;
			this.v2 = v2;
		}
	}

	class PairRecoder{
		int v;
		Vector<Pair> pairs = new Vector<Pair>();
		PairRecoder(int v,int i,int j){
			this.v = v;
			this.pairs.add(new Pair(i,j));
		}
	}

	class Four{
		List<Integer> num;
		Four(int v1,int v2,int v3,int v4){
			this.num = new ArrayList<Integer>();
			num.add(v1);
			num.add(v2);
			num.add(v3);
			num.add(v4);
		}
	}
	class OrderedFour extends Four{
		OrderedFour(int v1,int v2,int v3,int v4) {
			super(v1, v2, v3, v4);
			Collections.sort(this.num);
		}
	}
}
时间: 2024-12-08 10:11:10

【leetcode with java】18 4Sum (On^2)的相关文章

【leetcode with java】32 Longest Valid Parentheses O(n)

这个题目leetcode上提示用动态规划,但是那样要O(n^2).我自己想出了一个O(n)的算法,并提交通过. [题目] Given a string containing just the characters '(' and ')', find the length of the longest valid (well-formed) parentheses substring. For "(()", the longest valid parentheses substring

156. Merge Intervals【LintCode by java】

Description Given a collection of intervals, merge all overlapping intervals. Example Given intervals => merged intervals: [ [ (1, 3), (1, 6), (2, 6), => (8, 10), (8, 10), (15, 18) (15, 18) ] ] Challenge O(n log n) time and O(1) extra space. 题意:给定一个

Java编程思想【Thinking in java】

Java编程思想[Thinking in java]目录:第1章 对象导论1.1抽象过程1.2每个对象都有一个接口1.3每个对象都提供服务1.4被隐藏的具体实现1.5复用具体实现1.6继承1.6.1“是一个”(is-a)与“像是一个”(is-like-a)关系1.7伴随多态的可互换对象1.8单根继承结构1.9容器1.9.1参数化类型(范型)1.10对象的创建和生命周期1.11异常处理:处理错误1.12并发编程1.13Java与Internet1.13.1Web是什么1.13.2客户端编程1.13

【Leetcode长征系列】Letter Combinations of a Phone Number

原题: Given a digit string, return all possible letter combinations that the number could represent. A mapping of digit to letters (just like on the telephone buttons) is given below. Input:Digit string "23" Output: ["ad", "ae"

【Leetcode长征系列】Merge k Sorted Lists

原题: Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity. 思路:两条两条地合并.时间复杂度为O(n),n为所有链表节点和. 代码: /** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) :

【leetcode 字符串处理】Compare Version Numbers

[leetcode 字符串处理]Compare Version Numbers @author:wepon @blog:http://blog.csdn.net/u012162613 1.题目 Compare two version numbers version1 and version1. If version1 > version2 return 1, if version1 < version2 return -1, otherwise return 0. You may assume

【Leetcode长征系列】Construct Binary Tree from Inorder and Postorder Traversal

原题: Given inorder and postorder traversal of a tree, construct the binary tree. Note: You may assume that duplicates do not exist in the tree. 思路:和上一题一样,后续我们可以通过最后一个值得到根的值,同样可以通过定位根的值得到左右子树的子集,递归求解即可. 代码: /** * Definition for binary tree * struct Tre

MongDB基础学习(七)—— 【MongoDB for Java】Java操作MongoDB

[MongoDB for Java]Java操作MongoDB 开发的产品为了融资,不停得改版,从第一版到现在最新版本,最后发现公司发展方向都变了,有最初电子商务改成VR内容提供者(没办法,要别人钱,就得按照别人的规划的战略走).本来本章节会放到后面再做讲解,无奈,部门需要做一次培训任务,我就想到拿Java操作MongoDB作为培训内容,开发环境和依赖jar如下: (1)开发环境: System:Windows IDE:eclipse Database:mongoDB2.6 Maven:apac

【Leetcode长征系列】Single Number II

原题: Given an array of integers, every element appears three times except for one. Find that single one. Note: Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory? 思路: 用一个32位的数组存每一位bit值之后.得到答案后每一位除