TCO2014的程式設計贏取門票的題目,大致是從一個陣列(大小為K),可以選取1~K個數,必須保證這n個數是從1~n,返回所有的選取方法個數。
思路:首先是得到從1開始連續的數,儲存每個數的個數。然後通過排列組合得到結果。
當時採用的Python編寫,大致的模樣是這樣(題目要求的類名就略去了):
def getNumber(type): c = [0] * len(type) s = 0 p = 0 for x in type: if x <= len(type): c[x-1] += 1 for i in c: if i == 0: return s else: if s == 0: s = i p = i else: p *= i s += p return s print getNumber([2]) print getNumber([1, 2]) print getNumber([1, 3, 2]) print getNumber([1, 1, 2]) print getNumber([1, 3, 2, 5, 7, 4, 5, 4]) print getNumber([1, 1, 2, 2, 3, 3, 4, 4, 5, 5])
之後嘗試了一下 Java 版本:
package org.huys.algo.problem; public class WinterAndCandies { public static int getNumber(int[] type) { int[] c = new int[type.length]; int s = 0; int p = 0; for (int i=0; i<type.length; i++) { if (type[i] <= type.length) { c[type[i]-1] += 1; } } for (int i=0; i<c.length; i++) { if (c[i] == 0) { return s; } else { if (s == 0) { s = c[i]; p = c[i]; } else { p *= c[i]; s += p; } } } return s; } public static void main(String[] args) { System.out.println(getNumber(new int[] {2})); System.out.println(getNumber(new int[] {1, 2})); System.out.println(getNumber(new int[] {1, 3, 2})); System.out.println(getNumber(new int[] {1, 1, 2})); System.out.println(getNumber(new int[] {1, 3, 2, 5, 7, 4, 5, 4})); System.out.println(getNumber(new int[] {1, 1, 2, 2, 3, 3, 4, 4, 5, 5})); } }
最近開始關注golang和swift,兩種語言有很多共通之處。golang沒有class,還是不免有些不適。
package main import "fmt" func getNumber(types []int) int { var s = 0 var p = 0 var c = make([]int, len(types)) for _, value := range types { if value <= len(types) { c[value-1] += 1 } } for _, i := range c { if i == 0 { return s } else { if s == 0 { s = i p = i } else { p *= i s += p } } } return s } func main() { fmt.Println(getNumber([]int {2})) fmt.Println(getNumber([]int {1, 2})) fmt.Println(getNumber([]int {1, 3, 2})) fmt.Println(getNumber([]int {1, 1, 2})) fmt.Println(getNumber([]int {1, 3, 2, 5, 7, 4, 5, 4})) fmt.Println(getNumber([]int {1, 1, 2, 2, 3, 3, 4, 4, 5, 5})) }
程式碼中主要是陣列相關操作。相對而言,Python 最靈活。Golang 中採用 Slice 語法,與同為C系語言的Java頗為接近。