GaryLeetCode学习笔记·叁(第十二周)

本文深入解析了LeetCode上的经典算法题目,包括报数序列、最大子序和、最后一个单词长度、二进制求和、加一、x的平方根等,提供了详细的解题思路和代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

38.报数

报数序列是一个整数序列,按照其中的整数的顺序进行报数,得到下一个数。其前五项如下:

  1. 1
    
  2. 11
    
  3. 21
    
  4. 1211
    
  5. 111221
    

1 被读作 “one 1” (“一个一”) , 即 11。
11 被读作 “two 1s” (“两个一”), 即 21。
21 被读作 “one 2”, “one 1” (“一个二” , “一个一”) , 即 1211。

给定一个正整数 n(1 ≤ n ≤ 30),输出报数序列的第 n 项。

注意:整数顺序将表示为一个字符串。

class Solution(object):
    def countAndSay(self, n):
        """
        :type n: int
        :rtype: str
        """
        if n==1:                                                    #类似于斐波拉契数,后面的数跟前面的数有关  
            return '1'  
        if n==2:  
            return '11'                                             #进行i=3时的循环时,它的上一项为'11'
        pre='11
        for i in range(3,n+1):                                      #用for循环不断去计算逼近最后一次
            res=''                                                  #结果,每次报数都要初始化  
            cnt=1                                                   #计数变量
            length=len(pre)                                         #遍历我们的上一项,所以记录它的长度
            for j in range(1,length):  
                if pre[j-1]==pre[j]:
                    cnt+=1                                          #相等则加一  
                else:                                                       
                    res+=str(cnt)+pre[j-1]                          #一旦遇到不同的变量,就更新结果
                    cnt=1                                           #重置为1 
            res+=str(cnt)+pre[j]                                    #把最后一项及它的数量加上
            pre=res                                                 #保存上一次的结果  
        return res

上周的笔记里对本题的叙述不够详尽,本周再进行补充。
根据报数的特点,我们可以根据上一项的结果推导下一项。我们遍历上一项,辅以计数变量统计一下某些数字出现的次数,同时要不断保存上一项。

53.最大字序和

给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。

示例:

输入: [-2,1,-3,4,-1,2,1,-5,4],
输出: 6
解释: 连续子数组 [4,-1,2,1] 的和最大,为 6。
进阶:

如果你已经实现复杂度为 O(n) 的解法,尝试使用更为精妙的分治法求解。

class Solution(object):
    def maxSubArray(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        if len(nums)==1:
            return nums[0]
        else:
            a=[nums[0]]
            for i in range(1,len(nums)):
                if nums[i-1]>0:
                    nums[i]=nums[i]+nums[i-1]
                a.append(nums[i])
            return max(a)

本题难度不大,可调试了很多次才通过。
关键在于,子序列必开始于正数(有正数存在时),用相邻两数之和去替换第二个数,并不断循环比较,替代。最终取替换后的最大数;若全是非正数,则要通过列表选择最大的那个数。
关于本题的进阶,分治法,待下周更新。

58.最后一个单词的长度

给定一个仅包含大小写字母和空格 ’ ’ 的字符串,返回其最后一个单词的长度。

如果不存在最后一个单词,请返回 0 。

说明:一个单词是指由字母组成,但不包含任何空格的字符串。

示例:

输入: “Hello World”
输出: 5

class Solution(object):
    def lengthOfLastWord(self, s):
        """
        :type s: str
        :rtype: int
        """
        a=[]
        b=0
        for i in s:
            if i ==' ':
                j=s.index(i)
                a.append(j)
                b+=1
        if len(a)!=0:
            return (len(s)-a[b-1]-1)
        else:
            return 0
            

上述解法不能解决连续空格的情况,求解决

66.加一

给定一个由整数组成的非空数组所表示的非负整数,在该数的基础上加一。

最高位数字存放在数组的首位, 数组中每个元素只存储一个数字。

你可以假设除了整数 0 之外,这个整数不会以零开头。

示例 1:

输入: [1,2,3]
输出: [1,2,4]
解释: 输入数组表示数字 123。
示例 2:

输入: [4,3,2,1]
输出: [4,3,2,2]
解释: 输入数组表示数字 4321。

class Solution(object):
    def plusOne(self, digits):
        """
        :type digits: List[int]
        :rtype: List[int]
        """
        a=0
        b=0
        for i in digits:
            a=a+i*10**(len(digits)-b-1)
            b=b+1
        a=a+1
        l=[]
        while a>0:
            b=a%10
            l.append(b)
            a=a//10
        l.reverse()
        return l
        

如果直接使用列表解决,难点在于进位,所以果断用简单粗暴的解法,列表元素转为数字,加一以后再转换回去。先前第九题回文数已经用过类似的且更难得转换方法了,在此不一一赘述。

67.二进制求和

给定两个二进制字符串,返回他们的和(用二进制表示)。

输入为非空字符串且只包含数字 1 和 0。

示例 1:

输入: a = “11”, b = “1”
输出: “100”
示例 2:

输入: a = “1010”, b = “1011”
输出: “10101”

class Solution(object):
    def addBinary(self, a, b):
        """
        :type a: str
        :type b: str
        :rtype: str
        """
        num=int(a,2)+int(b,2)
        ans=bin(num)
        return ans[2:]

基本思路就是将二进制字符串转换为十进制,相加后在转换回二进制。一个偷懒操作就是用int( )和bin()函数,解决所有。但要注意,bin()函数得到的‘0bxxxxxxxx’,所以要取[2:]项
函数积累:
int(x, base=10)
顺便记录一下python下各类进制转换
dec = int(input(“输入数字:”))
print(“十进制数为:”, dec)
print(“转换为二进制为:”, bin(dec))
print(“转换为八进制为:”, oct(dec))
print(“转换为十六进制为:”, hex(dec))

如果不偷懒的话,就有些麻烦了

class Solution(object):
    def addBinary(self, a, b):
        """
        :type a: str
        :type b: str
        :rtype: str
        """
        num1=num2=0
        z=0
        while(1):                                       #表示会循环执行后面的语句
            if len(a) == 0:
                break
            num1=num1+pow(2,z)*int(a[-1])
            a=a[:-1]
            z+=1
        z = 0
        while (1):
            if len(b) == 0:
                break
            num2 = num2 + pow(2, z) * int(b[-1])
            b = b[:-1]
            z += 1
        sum = num1+num2
        sum = str(bin(sum)[2:])
        return sum

69.x的平方根

实现 int sqrt(int x) 函数。

计算并返回 x 的平方根,其中 x 是非负整数。

由于返回类型是整数,结果只保留整数的部分,小数部分将被舍去。

示例 1:

输入: 4
输出: 2
示例 2:

输入: 8
输出: 2
说明: 8 的平方根是 2.82842…,
由于返回类型是整数,小数部分将被舍去。

class Solution(object):
    def mySqrt(self, x):
        """
        :type x: int
        :rtype: int
        """
        min = 0
        max = x
        mid = x//2
        while min<=max:
            m = mid*mid
            if m>x:
                max = mid-1
            elif m<x:
                min = mid+1
            else:
                return mid
                break
            mid = (min+max)//2
        return mid        

本题需要用到一个之前没有接触过的方法——二分查找,不过在高中学过类似思想,用二分法近似解方程的根。
首先,表中元素是按升序排列,将表中间位置记录的关键字与查找关键字比较,如果两者相等,则查找成功;否则利用中间位置记录将表分成前、后两个子表,如果中间位置记录的关键字大于查找关键字,则进一步查找前一子表,否则进一步查找后一子表。重复以上过程,直到找到满足条件的记录,使查找成功,或直到子表不存在为止,此时查找不成功。
应用到本题上,先取出上界x与下界0,中间值则为x//2。判断mid的平方与x的大小关系,相等就查找成功,返回并结束循环即可;前者大,更改上界为mid-1,计算新mid值,开始新循环;后者小,更改下界为mid+1,计算新mid,开始新循环。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值