2019/11/15【组合总和II】

【题目一】

给定一个数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。

candidates 中的每个数字在每个组合中只能使用一次。

说明:

所有数字(包括目标数)都是正整数。
解集不能包含重复的组合。 
示例 1:

输入: candidates = [10,1,2,7,6,1,5], target = 8,
所求解集为:
[
  [1, 7],
  [1, 2, 5],
  [2, 6],
  [1, 1, 6]
]


示例 2:

输入: candidates = [2,5,2,1,2], target = 5,
所求解集为:
[
  [1,2,2],
  [5]
]

 

解题脚本:

#!/bin/bash
#组合总和II
#author:yzt 2019-11-15
#
first_step(){
        zuheshu=`echo "$2"|sed 's#\[\|\]##g'|sed 's#,# #g'`
        first_nums=`cat tmp1.txt`
        cat /dev/null > tmp2.txt
        for i in $first_nums
        do
                for j in $zuheshu
                do
                        echo "$i+$j">>tmp2.txt
                done
        done
        cat /dev/null >tmp1.txt
        while read line
        do
                pk=`echo "$line"|bc`
                if [ $pk -eq $1 ];then
                        echo "$line" >>tmp3.txt
                elif [ $pk -lt $1 ];then
                        echo "$line">>tmp1.txt
                fi
        done < tmp2.txt
        cat /dev/null >tmp4.txt
        if [ ! -s tmp1.txt ];then
                content=`cat tmp3.txt|sed 's#^..##'|sed 's#+#,#g'`
                for i in $content
                do
                    echo "$i"|sed 's#,#\n#g'|sort|sed ":a;N;s/\n/,/g;ta" >>tmp4.txt
                done
                cat tmp4.txt |sort| uniq >tmp5.txt

                while read line1
                do
                        flag='11'
                        echo "$line1"|sed 's#,#\n#g'|uniq -c >tmp7.txt
                        while read line
                        do
                                ceshu=""
                                first=`echo "$line"|awk '{print $1}'`
                                second=`echo "$line"|awk '{print $2}'`
                                ceshu=`awk -v j=$first -v k=$second '{if($2==k&&$1>=j){print $2}}' tmp6.txt`
                                test -z $ceshu && flag=22 && break
                        done < tmp7.txt
                        if [ $flag = '11' ];then
                                echo "$line1"
                        fi
                done < tmp5.txt
                exit 0
        fi
        first_step "$target" "$shuzu1"
}
echo "0" > tmp1.txt
read -t 15 -p "请输入一个目标值:" target1
read -t 30 -p "请输入一组可使用的数组:" shuzu2
export target=`echo "$target1"|bc`
export shuzu1=$shuzu2
cat /dev/null > tmp5.txt
cat /dev/null > tmp3.txt
echo "$shuzu1"|sed 's#\[\|\]##g'|sed 's#,#\n#g'|sort|uniq -c >tmp6.txt
first_step "$target" "$shuzu1"

 

 

脚本逻辑:

第一:由于是无重复组合,笔者在这几天尝试再次使用迭代来直接求解,但发现迭代并不适合动态的处理对象,如本题中的无重复组合,所以笔者放弃了直接使用迭代求解

第二:此题的答案就在前一道【组合总和】的输出中,只需对每个输出与组合进行比对即可。如:题目提供的组合【2,3,5】中,只有1个2;1个3;1个5。如果和为8,第一道题的答案为:[2,2,2,2][2,3,3][3,5]等,对于每一个答案,只要单个元素比如[2,2,2,2]中有4个2,那么这与题目提供的组合不匹配,所以不是第二道题答案;对于[3,5],有1个3;1个5,且5的元素存在于题目提供的组合,且5的元素个数少于或等于题目提供中5的元素个数,所以为第二道题的答案。

第三:ceshu=`awk -v j=$first -v k=$second '{if($2==k&&$1>=j){print $2}}' tmp6.txt` 是第二步的关键命令

脚本效果:

[root@localhost leetcode]# ./zuhezonghe3.sh
请输入一个目标值:8
请输入一组可使用的数组:10,1,2,7,6,1,5
1,1,6
1,2,5
1,7
2,6
[root@localhost leetcode]# ./zuhezonghe3.sh
请输入一个目标值:5
请输入一组可使用的数组:2,5,2,1,2
1,2,2
5

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值