2021-07-21:一张扑克有3个属性,每种属性有3种值(A、B、C),比如"AAA",第一个属性值A,第二个属性值A,第三个属性值A,比如"BCA",第一个属性值B,第二个属性值C,第三个属性值A。给定一个字符串类型的数组cards[],每一个字符串代表一张扑克,从中挑选三张扑克,一个属性达标的条件是:这个属性在三张扑克中全一样,或全不一样,挑选的三张扑克达标的要求是:每种属性都满足上面的条件。比如:"ABC"、"CBC"、"BBC",第一张第一个属性为"A"、第二张第一个属性为"C"、第三张第一个属性为"B",全不一样;第一张第二个属性为"B"、第二张第二个属性为"B"、第三张第二个属性为"B",全一样;第一张第三个属性为"C"、第二张第三个属性为"C"、第三张第三个属性为"C",全一样;每种属性都满足在三张扑克中全一样,或全不一样,所以这三张扑克达标。返回在cards[]中任意挑选三张扑克,达标的方法数。

福大大 答案2021-07-26:

时间紧。思路见代码。

代码用golang编写。代码如下:

import (
    "container/list"
    "fmt"
)

func main() {
    cards := []string{"ABC", "AAC", "ACC"}
    ret := ways2(cards)
    fmt.Println(ret)

}

func ways2(cards []string) int {
    counts := make([]int, 27)
    for _, s := range cards {
        counts[(s[0]-'A')*9+(s[1]-'A')*3+(s[2]-'A')*1]++
    }
    ways := 0
    for status := 0; status < 27; status++ {
        n := counts[status]
        if n > 2 {
            ways += twoSelectOne(n == 3, 1, n*(n-1)*(n-2)/6)
        }
    }
    path2 := list.New().Init()
    for i := 0; i < 27; i++ {
        if counts[i] != 0 {
            path2.PushBack(i)
            ways += process2(counts, i, path2)
            path2.Remove(path2.Back())
        }
    }
    return ways
}

func twoSelectOne(c bool, a int, b int) int {
    if c {
        return a
    } else {
        return b
    }
}

// 之前的牌面,拿了一些    ABC  BBB  ...
// pre = BBB
// ABC  ...
// pre  = ABC
// ABC BBB CAB
// pre = CAB
// 牌面一定要依次变大,所有形成的有效牌面,把方法数返回
func process2(counts []int, pre int, path2 *list.List) int {
    if path2.Len() == 3 {
        return getWays2(counts, path2)
    }
    ways := 0
    for next := pre + 1; next < 27; next++ {
        if counts[next] != 0 {
            path2.PushBack(next)
            ways += process2(counts, next, path2)
            path2.Remove(path2.Back())
        }
    }
    return ways
}

func getWays2(counts []int, path2 *list.List) int {
    v1 := path2.Front().Value.(int)
    v2 := path2.Front().Next().Value.(int)
    v3 := path2.Front().Next().Next().Value.(int)
    for i := 9; i > 0; i /= 3 {
        cur1 := v1 / i
        cur2 := v2 / i
        cur3 := v3 / i
        v1 %= i
        v2 %= i
        v3 %= i
        if (cur1 != cur2 && cur1 != cur3 && cur2 != cur3) || (cur1 == cur2 && cur1 == cur3) {
            continue
        }
        return 0
    }
    v1 = path2.Front().Value.(int)
    v2 = path2.Front().Next().Value.(int)
    v3 = path2.Front().Next().Next().Value.(int)
    return counts[v1] * counts[v2] * counts[v3]
}

执行结果如下:
在这里插入图片描述


左神java代码