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

 

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