Leetcode第五周周赛

第一题: 400. Nth Digit

这道题用暴力的直接写出从1到n的所有数字组合而成的字符串会超时。
一种解法是:
先计算出第n个字符是属于哪个数字的。边计算边统计之前的字符个数total。
然后得到这个数字后,将这个数字转为字符串,并取n-total-1这个下标的字符,就是所求。

func findNthDigit(n int) int {
    i := 0
    mark, l := 1, 0
    total := 0
    for i = 1; total < n; i++ {
        if i >= mark {
            total += l + 1
            l++
            mark *= 10
        } else {
            total += l
        }
    }
    i--
    total -= l
    t := strconv.Itoa(i)
    return int(t[n-total-1] - '0')
}

第二题:401. Binary Watch

没过,应该是题目有问题。题目中说顺序无所谓但是实际上顺序貌似还是有关系的。
用二进制来进行计算。
先递归的计算出所有可能的num情况。然后将对应的num读为时间即可。

var b = []int{1, 2, 4, 8, 16, 32, 64, 128, 256, 512}
var ret []string

func readTime(num int) {
    str := ""
    t := num >> 6
    if t >= 12 {
        return
    }
    str += strconv.Itoa(t) + ":"
    t = num & 63
    if t >= 60 {
        return
    }
    if t < 10 {
        str += "0" + strconv.Itoa(t)
    } else {
        str += strconv.Itoa(t)
    }
    ret = append(ret, str)
}
func help(now, num, idx int) {
    if num == 0 {
        readTime(now)
        return
    }
    if idx >= 10 {
        return
    }
    help(now, num, idx+1)
    help(now|b[idx], num-1, idx+1)
}
func readBinaryWatch(num int) []string {
    ret = []string{}
    if num == 0 {
        return []string{"0:00"}
    }
    for i := 0; i < len(b); i++ {
        help(b[i], num-1, i+1)
    }
    return ret
}

第三题:402. Remove K Digits

在裁剪的过程中,如果要裁剪掉k个字符,那么在一个字符串中,前k+1一个字符中一定会有至少一个字符被保留下来。所以算法的目的就是递归的找到这个字符,并对这个字符之后的字符串继续进行裁剪,直到得到最后的结果。
另外,题目中要求不能有0,所以在得到结果之后还要去掉首部的0。

var res string
func help(num string, k int) {
    if k <= 0{
        res = res + num
        return
    }
    if k >= len(num){
        return ;
    }
    minIdx := 0
    for i:=1;i<=k;i++{
        if num[i] < num[minIdx]{
            minIdx = i
        }
    }

    res = res + string(num[minIdx])
    new := num[minIdx+1:]
    help(new,k - minIdx)

}

func removeKdigits(num string, k int) string {
    res = ""
    help(num,k)
    i:=0
    for i=0;i<len(res)&&res[i]=='0';i++{
    }
    if i<len(res){
        res = res[i:]
    }else{
        res = "0"
    }
    return res
}

第四题:403. Frog Jump

很明显的递归的例子。
用一个映射来讲stones[下标]距离 改成 map[距离]下标.
然后从0开始起跳。距离为1。
每一次进行判断,首先是是不是最后一个石头了,是则返回true。程序over。
然后判断判断下目前所在的石头是哪一个。(检索map[stone[idx]+stp]即可知道,为0即不存在,返回false。)
接下来就是继续进行跳跃,分别尝试跳跃stp,stp+1,stp-1的距离即可。需要注意stp==0的时候是没有意义的,直接返回false.

var m map[int]int

func help(stones []int, idx int, stp int) bool {
    if stp == 0 {
        return false
    }
    if idx == len(stones)-1 {
        return true
    }
    if m[stones[idx]+stp] == 0 {
        return false
    }
    idx = m[stones[idx]+stp]
    return help(stones, idx, stp-1) || help(stones, idx, stp+1) || help(stones, idx, stp)

}
func canCross(stones []int) bool {
    m = make(map[int]int)
    for i := 0; i < len(stones); i++ {
        m[stones[i]] = i
    }
    return help(stones, 0, 1)
}

你可能感兴趣的:(leetcode)