问题
Problem statement:
// m is the number, n is upto-length of subsequences
// m = 20125, n =3 should print 201, 202, 205, 212, 215, 225, 012, 015, 125
// m = 20125, n =2 should print 20, 21, 22, 25, 01, 02, 05, 12, 15, 25
// m = 20125, n =1 should print 2, 0, 1, 2, 5
// m = 20125, n =4 should print 2012, 2015, 2125, 0125, 2025
// m = 20125, n =5 should print 20125
Below is the recursive solution implemented in GoLang:
package recursion
import (
"fmt"
"strconv"
)
// m is the number, n is upto-length of subsequences
// m = 20125, n =3 should print 201, 202, 205, 212, 215, 225, 012, 015, 125
// m = 20125, n =2 should print 20, 21, 22, 25, 01, 02, 05, 12, 15, 25
// m = 20125, n =1 should print 2, 0, 1, 2, 5
// m = 20125, n =4 should print 20125
func PrintSubSequence(m int, n int) {
numDigits := digits(m)
if n >= 1 && numDigits >= n { // m != 0
for i := 1; i <= numDigits-n+1; i++ { // tree recurion
firstInvocToIter := true
var slice []string
var findSubSequence func(int, int)
findSubSequence = func(m int, n int) {
if n == 1 { // base case
for m != 0 {
slice = append(slice, strconv.Itoa(m%10))
m = m / 10
}
return
} else {
if firstInvocToIter {
firstInvocToIter = false
findSubSequence(m/tenToThePower(i), n-1)
} else {
findSubSequence(m/10, n-1)
}
for i, value := range slice {
slice[i] = value + strconv.Itoa(m%10)
}
}
}
findSubSequence(m, n) // (20125, 3)
fmt.Println(slice)
}
} else {
return
}
PrintSubSequence(m/10, n)
}
func tenToThePower(times int) int {
number := 1
for times > 0 {
number *= 10
times--
}
return number
}
// Return the number of the digits of positive integer n
func digits(n int) int {
if n <= 0 {
return 0
} else if n < 10 {
return 1
} else {
allButLast, _ := split(n)
return digits(allButLast) + 1
}
}
package main
import (
"github.com/myhub/cs61a/recursion"
)
func main() {
recursion.PrintSubSequence(20125, 2) // prints duplicates as per debugging
recursion.PrintSubSequence(20125, 3) // Works fine
}
For recursion.PrintSubSequence(20125, 3)
output is fine:
[125 025 225]
[015 215]
[205]
[012 212]
[202]
For recursion.PrintSubSequence(20125, 2)
output has duplicates(problem output):
[25 15 05 25] --> Valid
[15 05 25] --> duplicate
[05 25] --> duplicate
[25] --> duplicate
[12 02 22] --> Valid
[02 22] --> duplicate
[22] --> duplicate
[01 21] --> Valid
[21] --> duplicate
[20] --> Valid
Does this require maintaining a set of strings? to include slice
in a set
or
How to handle duplicates? Looks like n==1
base case of tree recursion is giving issue?
回答1:
If you convert your integer into string then it will more easier I think.
func PrintSubSequence(digits string, tmp string, idx int, sz int) {
if len(tmp) == sz { // if size reach then print
fmt.Println(tmp)
return
}
// here idx indicate in tmp string we already use till idx-1
for i := idx; i < len(digits); i++ {
tmp2 := tmp + string(digits[i]) // Add new digit in new variable to pass in recursion without change current tmp
PrintSubSequence(digits, tmp2, i+1, sz)
}
}
func main() {
PrintSubSequence(strconv.Itoa(21025), "", 0, 2) // Convert interger into string
}
Full code in go playground here
回答2:
Algo here:-
- You need to think from a each digit perspective. So, when you generating subsequence, either a digit can be part of the subsequence, or it cannot be.
- When you consider a particular digit, increment a counter (say, currentLength). Add the sequence which is formed till now to a Set to avoid duplicates.
- If the currentLength counter has reached your given upto-length, then stop the formation of current subsequence.
- Move onto next sequence formation.
来源:https://stackoverflow.com/questions/62225180/tree-recursion-print-subsequence-of-a-given-number