[LeetCode] 4Sum 四數之和解法(本算法n數之和都能解)

四數之和 

給一個包含n個數的整數數組S,在S中找到所有使得和爲給定整數target的四元組(a, b, c, d)。

 注意事項

四元組(a, b, c, d)中,需要滿足a <= b <= c <= d

答案中不可以包含重複的四元組。

例如,對於給定的整數數組S=[1, 0, -1, 0, -2, 2] 和 target=0. 滿足要求的四元組集合爲:

(-1, 0, 0, 1)

(-2, -1, 1, 2)

(-2, 0, 0, 2)


    這是一道數組求和的問題,看了網上很多解答的算法,比較流行的是一個先排序,然後選兩個數字,接着後面用兩個指針分別指向剩下數組開始和結束,逐步移向中間求和看和targer是否相等,但是這樣的算法感覺實現起來太不優雅了。想到一個深度遍歷的算法,可以到達同樣的效果,而且以後無論多少個數求和,都能解決。代碼如下:

 public ArrayList<ArrayList<Integer>> fourSum(int[] numbers, int target) {
		Arrays.sort(numbers);
		ArrayList<ArrayList<Integer>> ret = new ArrayList<>();
		dfs(ret, new ArrayList<Integer>(), numbers, 0, target);
		return ret;
	}
	
	private void dfs(ArrayList<ArrayList<Integer>> ret, ArrayList<Integer> condidate, int[] numbers, int curIndex,
			int target) {
	    // 以後求n數和,只要改這裏就能解決,比如4改爲3,改爲5
		if (condidate.size() == 4) {
			int total = getSum(condidate);
			if (total == target) {
				ret.add(new ArrayList<>(condidate));
			}
			return;
		}
		if (curIndex > numbers.length - 1) {
			return;
		}
		for (int i = curIndex; i < numbers.length; i++) {
		    // 如果是一樣的數字,直接忽略,否則會有重複的答案
			if (i != curIndex && numbers[i] == numbers[i - 1]) {
				continue;
			}
			condidate.add(numbers[i]);
			// 如果已經大於target,並且當前數字大於0,再循環加下去已經沒有意義了,因爲只會更大,直接return
			if (getSum(condidate) > target && numbers[i] > 0) {
				if (!condidate.isEmpty()) {
					condidate.remove(condidate.size() - 1);
				}
				return;
			}
			dfs(ret, condidate, numbers, i + 1, target);
			if (!condidate.isEmpty()) {
				condidate.remove(condidate.size() - 1);
			}
		}
	}

	private int getSum(ArrayList<Integer> condidate) {
		int total = 0;
		for (Integer num : condidate) {
			total += num;
		}
		return total;
	}




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章