LeetCode40 Combination Sum II 解析
详细见:leetcode.com/problems/combination-sum-ii
C和Python的去重算法,应该记住。
Java是很久之前写的,并不好。
规则是:相同数字。
1,前面选了,后面一定要选。
2,前面没选,后面可选可不选。
注意一定要选到最后一位,才能判断。
Java Solution: github
package leetcode;import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;public class P040_CombinationSumII {public static void main(String[] args) {
// System.out.println(new Solution2().combinationSum2(new int[] {10, 1, 2, 7, 6, 1, 5}, 8));
// System.out.println(new Solution2().combinationSum2(new int[] {2, 5, 2, 1, 2}, 5));System.out.println(new Solution2().combinationSum2(new int[] {3,1,3,5,1,1}, 8));}/** 15 ms* 26.62%*/static class Solution2 {List<List<Integer>> ans = null;boolean[] isAnswer = null;int[] index1 = null, index2 = null;public List<List<Integer>> combinationSum2(int[] candidates, int target) {if (candidates == null || candidates.length == 0)return ans;Arrays.sort(candidates);ans = new LinkedList<List<Integer>>();isAnswer = new boolean[candidates.length];index1 = new int[candidates.length];index1[0] = 0;for (int i = 1; i != candidates.length; i ++)index1[i] = candidates[i] == candidates[i - 1] ? index1[i - 1] : i;index2 = new int[candidates.length];index2[index2.length - 1] = index2.length - 1;for (int i = index2.length - 2; i != -1; i --)index2[i] = candidates[i] == candidates[i + 1] ? index2[i + 1] : i;searchAllAns(candidates, -1, target);return ans;}private void searchAllAns(int[] candidates, int index, int target) {if (target == 0) {List<Integer> answer = new LinkedList<Integer>();for (int i = 0; i != candidates.length; i ++)if (isAnswer[i])answer.add(candidates[i]);if (answer.size() != 0)ans.add(answer);}if (index == candidates.length || target < 0)return;for (int i = index + 1; i != candidates.length; i ++) {if (isAnswer[i])continue;if (index1[i] == i && index2[i] == i) {isAnswer[i] = true;searchAllAns(candidates, i, target - candidates[i]);isAnswer[i] = false;} else {int num = index2[i] - index1[i] + 1;i = index2[i];for (int j = 1; j <= num; j ++) {for (int k = 0; k != j; k ++)isAnswer[k + index1[i]] = true;searchAllAns(candidates, i, target - j * candidates[i]);for (int k = 0; k != j; k ++)isAnswer[k + index1[i]] = false;}}}}}
}
C Solution: github
/*
url: leetcode.com/problems/combination-sum-ii/AC 12ms 27.27%
*/#include <stdio.h>
#include <stdlib.h>//array list starttypedef int* T;
typedef struct al sal;
typedef struct al * pal;struct al {int capacity;int size;T* arr;
};void al_expand_capacity(pal l) {T* new_arr = (T*) malloc(sizeof(T) * (l->capacity * 2 + 1));int i = 0;for (i = 0; i < l->capacity; i ++)new_arr[i] = l->arr[i];free(l->arr);l->arr = new_arr;l->capacity = l->capacity * 2 + 1;
}void al_add_last(pal l, T v) {if (l->capacity == l->size) al_expand_capacity(l);l->arr[l->size] = v;l->size ++;
}void al_add_first(pal l, T v) {int i = 0;if (l->capacity == l->size) al_expand_capacity(l);for (i = l->size; i > 0; i --)l->arr[i] = l->arr[i - 1];l->arr[0] = v;l->size ++;
}void al_add_to_index(pal l, T v, int index) {int i = 0;if (index > l->size) return;if (l->capacity == l->size) al_expand_capacity(l);for (i = l->size - 1; i >= index; i --) {l->arr[i+1] = l->arr[i];}l->arr[index] = v;l->size ++;
}//if T is ptr, need to free l->size - 1
void al_remove_last(pal l) {if (l->size == 0) return;l->arr[l->size - 1] = 0; //or NULL and freel->size --;
}//if T is ptr, need to free 0
void al_remove_first(pal l) {int i = 0;if (l->size == 0) return;l->arr[0] = 0; //or NULL and freefor (i = 1; i < l->size; i ++) {l->arr[i - 1] = l->arr[i];}l->size --;
}T* al_convert_to_array_free_l(pal l) {T* arr = l->arr;free(l);return arr;
}T al_access_by_index(pal l, int index) {if (index >= l->size || index < 0) return 0;return l->arr[index];
}void al_free_all(pal l) {free(l->arr);free(l);
}void al_print(pal l) {int i = 0;if (l->size == 0) return;for (i = 0; i < l->size; i ++)printf("%d ", l->arr[i]);printf("\r\n");
}//array list end//quick srot start//[l, r]
int _partition(int* n, int l, int r) {int s = *(n + l);while (l < r) {while (l < r && *(n + r) >= s) r --;*(n + l) = *(n + r);while (l < r && *(n + l) <= s) l ++;*(n + r) = *(n + l);}*(n + l) = s;return l;
}//[l, r)
void _quick_sort(int* n, int l, int r) {int p = 0;if (l < r) {p = _partition(n, l, r - 1);_quick_sort(n, l, p);_quick_sort(n, p + 1, r);}
}void quick_sort(int* n, int s) {_quick_sort(n, 0, s);
}//quick sort endvoid search(pal l, int* c, int ci, int cn, int** rn, int t, int sign, int* s, int si) {int* temp = NULL, i = 0;if (t == 0 && ci == cn) {temp = (int*) malloc(sizeof(int) * si);for (i = 0; i < si; i ++)temp[i] = s[i];(*rn)[l->size] = si;al_add_last(l, temp);return;}if (t < 0 || ci == cn) return;// sign = 1 and c[ci - 1] == c[ci] : notif (!(sign && c[ci - 1] == c[ci])) {search(l, c, ci + 1, cn, rn, t, 0, s, si);}s[si] = c[ci];search(l, c, ci+1, cn, rn, t-c[ci], 1, s, si+1);
}int** combinationSum2(int* c, int cn, int t, int** rn, int* r) {int* s = (int*) malloc(sizeof(int) * cn);pal l = (pal) malloc(sizeof(sal));l->size = 0;l->capacity = 16;l->arr = (T*) malloc(sizeof(T) * l->capacity);quick_sort(c, cn);*rn = (int*) malloc(sizeof(int) * (cn*cn));search(l, c, 0, cn, rn, t, 0, s, 0);*r = l->size;free(s);return al_convert_to_array_free_l(l);
}int main() {int c[] = {1, 1};int cn = 2; int t = 1;int* rn = NULL;int r = 0;int** ans = combinationSum2(c, cn, t, &rn, &r);int i = 0, j = 0;printf("r is %d\r\n", r);for (i = 0; i < r; i ++) {for (j = 0; j < rn[i]; j ++)printf("%d ", ans[i][j]);printf("\r\n");free(ans[i]);}free(ans);return 0;
}
Python Solution: github
#coding=utf-8'''url: leetcode.com/problems/combination-sum-ii/@author: zxwtry@email: zxwtry@qq.com@date: 2017年4月6日@details: Solution: 286ms 16.23%
'''class Solution(object):def search(self, ans, s, si, c, ci, cn, t, sign):if t == 0 and ci == cn:ans_t=[0]*sifor i in range(si):ans_t[i] = s[i]ans.append(ans_t)returnif t < 0 or ci == cn:returnif not(sign and c[ci - 1] == c[ci]):self.search(ans, s, si, c, ci+1, cn, t, False)s[si] = c[ci]self.search(ans, s, si+1, c, ci+1, cn, t-c[ci], True)def combinationSum2(self, c, t):""":type c: List[int]:type t: int:rtype: List[List[int]]"""cn = 0 if c == None else len(c)if cn == 0: return []c.sort(key=None, reverse=False)s, si, ans=[0]*cn, 0, []self.search(ans, s, si, c, 0, cn, t, False)return ansif __name__ == "__main__":print(Solution().combinationSum2([1,1], 1))
LeetCode40 Combination Sum II 解析相关推荐
- 40. Combination Sum II 组合总和 II
给定一个数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合. candidates 中的每个数字在每个组合中只能使用一次. ...
- Combination Sum 和Combination Sum II
这两道题的基本思路和combination那一题是一致的,也是分治的方法. 其中combination Sum复杂一点,因为每个数可能用多次.仔细分析下,本质上也是一样的.原来是每个数仅两种可能.现在 ...
- 递归/回溯:Combination Sum II数组之和
问题如下: 已知一组数(其中有重复元素),求这组数可以组成的所有子集中,子 集中的各个元素和为整数target的子集,结果中无重复的子集. 例如: nums[] = [10, 1, 2, 7, 6, ...
- C#LeetCode刷题之#40-组合总和 II(Combination Sum II)
目录 问题 示例 分析 问题 该文章已迁移至个人博客[比特飞],单击链接 https://www.byteflying.com/archives/3666 访问. 给定一个数组 candidates ...
- 40. Combination Sum II
避免这个循环的重复 所以i>position && nums[i] == nums[i-1] 1 class Solution { 2 List<List<Integ ...
- Combination Sum II
1 解析 这道题是则就是上一道题的进阶版,此题可以出现相同的元素,例如[1 1 1 7] 目标值为8,那么难点就在于如何去除重复的情况,只保留[1 7]这种情况. 2 思路 都是采用DFS求解,思路和 ...
- 40. Combination Sum II **
description: 给定target, 求给定数列中找到几个数(其中的数不可以重复使用,且一组数有几个也不做限制)的和为target,和上面那个题一毛一样的,就改一下下标就行了,背下来背下来背下 ...
- 【DFS】LeetCode 40. Combination Sum II
Solution1:我的答案 同39题.DFS时间复杂度O(2n)O(2n)O(2^n),空间复杂度O(kn)O(kn)O(kn),k是最终答案的数量,n是元素个数 去重,用set,比较偷懒的做法 c ...
- Lintcode: k Sum II
Given n unique integers, number k (1<=k<=n) and target. Find all possible k integers where the ...
最新文章
- 设置静态固定ip地址
- Java 转型问题(向上转型和向下转型)
- 基于暗通道优先算法的去雾应用Matlab
- OpenGL计算着色器
- 题解【黑匣子_NOI导刊2010提高(06)】(洛谷P1801)
- LeetCode 336. 回文对(哈希map/Trie树)
- Dubbo :广播模式下Can't assign requested address问题
- mysql慢查询 表级锁_三分钟了解Mysql的表级锁——《深究Mysql锁》
- Centos下安装MySQL全过程(linux下安装MySQL)
- 大数据系统应包含哪些功能模块
- 山西好点的计算机专科学校排名及分数线,2019-2020山西专科学校排名及分数线(理科+文科)...
- tcp多进程文件传输服务器,TCP/IP网络编程 Chap10. 多进程服务器端
- linux 安装Python3 并安装Python Blog Wagtail
- 混沌时间序列的 rbf 预测
- C++ Bayer图像格式,使用GDAL进行格式转换。
- 3Dtouch 基本原理
- c#大批量Exce数据l导入数据库
- gre 填空31-42
- TortoiseGit基本操作
- 怎么压缩png图片的大小?4个简单高效工具分享