详细见: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 解析相关推荐

  1. 40. Combination Sum II 组合总和 II

    给定一个数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合. candidates 中的每个数字在每个组合中只能使用一次. ...

  2. Combination Sum 和Combination Sum II

    这两道题的基本思路和combination那一题是一致的,也是分治的方法. 其中combination Sum复杂一点,因为每个数可能用多次.仔细分析下,本质上也是一样的.原来是每个数仅两种可能.现在 ...

  3. 递归/回溯:Combination Sum II数组之和

    问题如下: 已知一组数(其中有重复元素),求这组数可以组成的所有子集中,子 集中的各个元素和为整数target的子集,结果中无重复的子集. 例如: nums[] = [10, 1, 2, 7, 6, ...

  4. C#LeetCode刷题之#40-组合总和 II(Combination Sum II)

    目录 问题 示例 分析 问题 该文章已迁移至个人博客[比特飞],单击链接 https://www.byteflying.com/archives/3666 访问. 给定一个数组 candidates ...

  5. 40. Combination Sum II

    避免这个循环的重复 所以i>position && nums[i] == nums[i-1] 1 class Solution { 2 List<List<Integ ...

  6. Combination Sum II

    1 解析 这道题是则就是上一道题的进阶版,此题可以出现相同的元素,例如[1 1 1 7] 目标值为8,那么难点就在于如何去除重复的情况,只保留[1 7]这种情况. 2 思路 都是采用DFS求解,思路和 ...

  7. 40. Combination Sum II **

    description: 给定target, 求给定数列中找到几个数(其中的数不可以重复使用,且一组数有几个也不做限制)的和为target,和上面那个题一毛一样的,就改一下下标就行了,背下来背下来背下 ...

  8. 【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 ...

  9. Lintcode: k Sum II

    Given n unique integers, number k (1<=k<=n) and target. Find all possible k integers where the ...

最新文章

  1. 设置静态固定ip地址
  2. Java 转型问题(向上转型和向下转型)
  3. 基于暗通道优先算法的去雾应用Matlab
  4. OpenGL计算着色器
  5. 题解【黑匣子_NOI导刊2010提高(06)】(洛谷P1801)
  6. LeetCode 336. 回文对(哈希map/Trie树)
  7. Dubbo :广播模式下Can't assign requested address问题
  8. mysql慢查询 表级锁_三分钟了解Mysql的表级锁——《深究Mysql锁》
  9. Centos下安装MySQL全过程(linux下安装MySQL)
  10. 大数据系统应包含哪些功能模块
  11. 山西好点的计算机专科学校排名及分数线,2019-2020山西专科学校排名及分数线(理科+文科)...
  12. tcp多进程文件传输服务器,TCP/IP网络编程 Chap10. 多进程服务器端
  13. linux 安装Python3 并安装Python Blog Wagtail
  14. 混沌时间序列的 rbf 预测
  15. C++ Bayer图像格式,使用GDAL进行格式转换。
  16. 3Dtouch 基本原理
  17. c#大批量Exce数据l导入数据库
  18. gre 填空31-42
  19. TortoiseGit基本操作
  20. 怎么压缩png图片的大小?4个简单高效工具分享

热门文章

  1. 一进制存在吗?为什么?
  2. SpringMVC个人理解(downpour 的SpringMVC深度探险的个人整理)
  3. react笔记_07组件实例化对象的三大属性
  4. linux如何卸载wps,Ubuntu菜鸟入门(三)—— 无用软件卸载,wps等常用软件安装...
  5. 论文笔记之Stein变分梯度下降
  6. 石化行业安全生产调度解决方案
  7. flutter 开发中问题盘锦
  8. # 英语四级 词根+例句
  9. 【archlinux】安装系统
  10. Android中WebP图片文件