持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第27天,点击查看活动详情
测试岗位也越来卷了,除了基本的功能测试外,还要有编程基础、脚本经验才脱颖而出。
怎么才能提高我们的编程能力呢,刷LeetCode是最佳的途径之一,话不多数,刷题走起~
一、题目描述:
-
题目内容
-
题目示例
-
题目提示
1 <= n <= 301 <= k <= 2n - 1
二、思路分析:
我们今天拿到本题是 leetcode 难度为中等题 779. 第K个语法符号。题目要求在给定的n行中找到指定的K的字符符号。题目中介绍n行字符排序特点:
- 从第一行开始,每一行字符索引从1开始计算
- 首行0,第二行0替换成01,第三行1替换成10,0110,第四行01101001...依次类推
- 每一行的符号都是0和1组成
根据题目描述,对于每一行都由上一行0和1替换组成,通过找规律递归遍历解答,思路如下:
-
方法一:dfs模拟
- 第n-1行的字符长度prelen是第n行的2的n-2的次方(2^(n-2))
- 当k大于上一行的字符长度prelen时,则n行k的字符与n-1行k-prelen字符互为相反
- 当k小于等于上一行的字符prelen时,则n行k的字符与n-1行k字符相同
- 根据题目中示列,n=4,k=6;递归路径(dfs(4,6)->dfs(3,2)->dfs(2,2)->dfs(1,2))
class Solution(object): def kthGrammar(self, n, k): """ :type n: int :type k: int :rtype: int """ def dfs(n,k): if n==1:return 0 # prelen = pow(2,n-2) prelen = 1<<(n-2) if k > prelen: return 0 if dfs(n-1,k-prelen) else 1 else: return dfs(n-1,k) return dfs(n,k)
-
方法二:找规律
- 构建n行字符符号,我们可以转换成一个二叉树形式
- 根节点为0,每一行按照0替换成10,1替换成10
- 在二叉树中,左孩子与父节点相同,右孩子与父节点相反
- 子节点(n,k),则其父节点位置为(n,(k+1)/2)
- 判断节点是左/右孩子,可以根据k奇偶性,k为奇数则为左孩子,k为偶数则为右孩子
class Solution(object): def kthGrammar(self, n, k): if n==1:return 0 ret = self.kthGrammar(n-1,(k+1)/2) return ret if k % 2 ==1 else 1-ret
三、总结:
本题是一道关于位运算概念,可以借用二叉树递归的思想来解答,只要发现左孩子与父节点一样,右孩子与父节点异或,同时借用k值来取求出父节点位置和左/右孩子特点就可以求出,AC提交记录如下:
- 时间复杂度:O(n),n为题目给定的行数
- 空间复杂度:O(n),n为递归遍历的深度
以上是本期内容,欢迎大佬们点赞评论,下期见~~~