第一题: 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)
}