zoukankan      html  css  js  c++  java
  • 40.组合总和Ⅱ

    40.组合总和Ⅱ

    给定一个数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。
    candidates 中的每个数字在每个组合中只能使用一次。
    说明:
    所有数字(包括目标数)都是正整数。
    解集不能包含重复的组合。

    • 跟上一题组合总和一样的解法
    • 这次规定只能使用一次数字,那么我们可以添加一个判定的数组
    • 数组的大小和candidates大小一致,判定数组的每一位对应candidates的每一位,在使用到这个数字的时候,在判定数组的相应位置写上1,代表我使用了这个数,在搜索完毕的时候归0,表示归还.
    class Solution {
        public List<List<Integer>> combinationSum2(int[] candidates, int target) {
            List<List<Integer>> result = new ArrayList<>();
            for (int i = 0; i < candidates.length; i++){
                List<Integer> temp = new ArrayList<>();
                // 判定用数字
                int[] pos = new int[candidates.length];
                temp.add(candidates[i]);
                // 使用时写上1
                pos[i] = 1;
                searchCandidatesToSum2(result,temp,candidates[i],pos,candidates,target);
                temp.remove((Integer) candidates[i]);
                // 搜索结束归0
                // 下面的函数内部逻辑 同理
                pos[i] = 0;
            }
    
            return result;
        }
    
        private void searchCandidatesToSum2(List<List<Integer>> result, List<Integer> temp, int tempSum, int[] pos, int[] candidates, int target) {
            // 与之前的文章一样的逻辑
            // 在此不多赘述
            if( tempSum > target ){
                return;
            }
            if( tempSum == target ){
                if( findResult(result,temp) ){
                    temp.sort(Comparator.naturalOrder());
                    result.add(new ArrayList<>(temp));
                }
                return;
            }
            for (int i = 0; i < candidates.length; i++) {
                if( pos[i] != 1 ){
                    temp.add(candidates[i]);
                    pos[i] = 1;
                    searchCandidatesToSum2(result,temp,tempSum+candidates[i],pos,candidates,target);
                    pos[i] = 0;
                    temp.remove((Integer)candidates[i]);
                }
            }
        }
        // 复制了之前的代码
        // 函数重用 XD
        private boolean findResult(List<List<Integer>> result, List<Integer> temp) {
            for (List<Integer> item :
                    result) {
                /**
                 * 当集合大小相同时进行比对
                 */
                if( item.size() == temp.size() ){
                    List<Integer> newItem = new ArrayList<>(item);
                    for (Integer i : temp) {
                        /**
                         * 当newItem中存在temp的第i个目标时
                         * 从newItem中删去当前目标相同的数字
                         */
                        if(newItem.contains(i)){
                            newItem.remove(i);
                        }
                    }
                    /**
                     * 若newItem的大小为0时
                     * 说明newItem与temp的内容完全相同
                     * 则返回false
                     */
                    if( newItem.size() == 0 ){
                        return false;
                    }
                }
            }
            return true;
        }
    }
  • 相关阅读:
    Nginx 反向代理多个后台服务端口
    微信小程序,横向布局,纵向布局
    Maven的标准settings.xml文件
    Springboot 复杂查询及SQL拼接笔记
    ElementUI 设置显示侧栏滚动条elscrollbar,隐藏横向滚动条
    让俺内牛满面的编辑器啊~
    Javascript 对话框 (遇到 Ajax Load无法加载问题)
    thinkpad s5 电源功率不足提示
    NAO机器人开发环境配置
    Choregraphe 2.8.6.23动作失效
  • 原文地址:https://www.cnblogs.com/hh09cnblogs/p/11601572.html
Copyright © 2011-2022 走看看