LeetCode779 第K个语法符号 python刷题Day5

    779.第K个语法符号

差一点今天就前功尽弃了,瘫在沙发上一时爽,一直瘫着废到老。想想昨天被一道评级为简单的题困住了。虽然我上学上的久,但我学的东西少啊。好了,开正题了,士可以一日不食而不能半日不学。

题目

在第一行我们写上一个 0。接下来的每一行,将前一行中的0替换为01,1替换为10。

给定行数 N 和序数 K,返回第 N 行中第 K个字符。(K从1开始)


例子:

输入: N = 1, K = 1
输出: 0

输入: N = 2, K = 1
输出: 0

输入: N = 2, K = 2
输出: 1

输入: N = 4, K = 5
输出: 1

解释:
第一行: 0
第二行: 01
第三行: 0110
第四行: 01101001

注意:

N 的范围 [1, 30].
K 的范围 [1, 2^(N-1)].


原题链接:https://leetcode-cn.com/problems/k-th-symbol-in-grammar
 

分析解题思路

      昨天刚发现leetcode可以用python,一直看到官方解题里有python,我一直以为只能选c++和Java,真是可以偷大懒了。把C++留给大神们去用吧。

拿到这道题,审题就审了半天,然后明白了,就是按规律排列的若干行,用01替换上一行的0,用10替换上一行的1。拿到手就是算,那我把这一行求出来不就知道这行第K个数字是什么了么,官方称之为暴力破解法。

如图:

解题思路

  1. 第一行为0
  2. 下一行与上一行对应,每一个0对应一个01,每一个1对应一个10
  3. 循环N行,输出第K个值

 

暴力破解代码如下

 

class Solution(object):
    def kthGrammar(self, N, K):
        lastrow = '0'
        rows = 1
        while rows < N:
            lastrow = "".join('01' if x == '0' else '10' for x in lastrow)
            rows += 1
        return int(lastrow[K-1])

根据上图所示,该算法的时间复杂度: O(2^N),时间复杂度呈指数级增加。当N的值稍微一大,程序运行会超时。

 

算法优化

经过观察,我们发现,不需要去计算第N行的所有数字,因为N行的第K个元素是受N-1行第K+1/2的元素所影响,当该值为0时,所求K值为1-K%2,当该值为1时,所求K值为K%2。因此,可以用递归优化求解。步骤如下:

  1. 设置递归出口N = 0时,返回值为0
  2. 返回N-1行第K+1/2个元素的值进行判断
  3. if 该值为0 返回1-K%2 ,else返回K%2

 

优化递归代码

class Solution(object):
    def kthGrammar(self, N, K):
        """
        :type N: int
        :type K: int
        :rtype: int
        """
        if N == 1 :
            return 0
        elif self.kthGrammar(N-1,(K + 1)/2) == 0 :
            return 1 - K % 2
        else:
            return K % 2

   

运行结果 

 

 该算法的时间复杂度减小到O(log(2^N))即O(N),提高了运算速度。

 

小结

希望不虚度每一天。依旧每日一句,共勉。

若新雪初霁,满月当空,下面平铺着皓影,上面流转着亮银,而你向我走来,月色与雪色之间,你是第三种绝色。

————余光中《绝色》

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值