持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第28天,点击查看活动详情
题目描述
这是 力扣上的 779. 第K个语法符号,难度为 中等。
题目分析
题目汇总给出一个表格,这个表格比较特殊,行索引开始,每一行的字符也是从索引开始,且表格的每一行中的数据是按照特殊方式分裂开来的,例如上一行中的会分裂成下一行的,上一行中的会分裂成下一行中的
题目要我们迅速的找到第 行的 第 个字符是还是
思考:
那么我们来稍微简单的写几行数据来模拟一下,看看有没有什么规律可循
| 0 |
|---|
| 01 |
| 0110 |
| 01101001 |
仔细看例子,我们可以看到第 行的字符个数是 ,并且仔细的我们还可以发现,第行的字符数,总是行的一半,且字符还有很有趣的关系
那就是第 i 行的全部字符是第行的前半部分, 行的后半部分也很有意思,后半部分是前半部分的翻转
此处的翻转意思是:
前半部分的 0 对应着后半部分的 1,前半部分的 1 ,对应这后半部分的 0
那么,看到这里,对于解决这道题是不是有了一些思路呢?
我们就可以将题目中要求我们找到,转换成了 (如果这个k 是大于当前行字符的一半,那么就要转换成前半段的字符),一直递归到的情况我们就可以找到答案了,那么我们就有这样的逻辑:
如果 的,咱们就可以直接返回
如果 的,且满足条件 ,满足这个条件,说明找当前行的第 k 个字符,已经是在当前行的后半段了,因此,我们就继续往上找,找上一行的 个字符的翻转
如果 的,且不满足条件 ,说明当前行要找的第 k 个字符在前半段,那么直接就找上一行的第 个字符即可,一直找到的时候
对于以上逻辑,已经非常清晰了
接下来,咱们就可以来实现编码了,咱们这次使用 golang 的方式来进行实现
Golang 的实现方式:
-
递归处理即可,每一次都判断当前行的第 k 个字符是否大于当前行的一半,若是,则找上一行对应位置的翻转
- 若不是则找上一行的 第 k 个位置的字符
func kthGrammar(n, k int) int {
if n == 1 {
return 0
}
// 判断 当前行的第 k 个字符,是否大于上一行的总个数
// 表示 k 的位置是当前行的后半部分了,那么就需要找到 当前行的第 k 个字符的位置在前半部分的对应翻转位置
if k > 1<<(n-2) {
return 1 ^ kthGrammar(n-1, k- 1<<(n-2))
}
// 若 k 是当前行的前半部分,那么不需要翻转
return kthGrammar(n-1, k)
}
这种实现方式,咱们的时间复杂度为 O(n),此处的 n 是表示表格的 n 行,空间复杂度也是 O(n),我们使用的是递归的方式,需要递归 n 行,占用栈空间
今天就到这里,若有偏差,还请斧正
欢迎点赞,关注,收藏
朋友们,你的支持和鼓励,是我坚持分享,提高质量的动力
好了,本次就到这里
技术是开放的,我们的心态,更应是开放的。拥抱变化,向阳而生,努力向前行。
我是阿兵云原生,欢迎点赞关注收藏,下次见~