LeetCode题集四

  • 简单题
  • 171. Excel表列序号
  • 172. 阶乘后的零
  • 189. 旋转数组
  • 中等题
  • 2. 两数相加
  • 3. 无重复字符的最长子串
  • 5. 最长回文子串
  • 6. Z 字形变换
  • 8. 字符串转换整数 (atoi)


简单题

171. Excel表列序号

题目:

5 lenet 代码python leetcode5 python_子串

思路:

26进制转10进制。

解法:

class Solution:
    def titleToNumber(self, s: str) -> int:

        if not s: 
            return 0

        n = len(s)
        res = 0
        
        for i in range(n):
            res += 26 ** (n-i-1)  * (ord(s[i]) -64)
        return  res

172. 阶乘后的零

题目:

5 lenet 代码python leetcode5 python_python_02

思路:

要在末位产生0,则必然是5×2,即使是原数中包含的0也可以分解,因此将题目简化为寻找阶乘中5的个数,即n//5,但是25又可以拆解成5×5,所以还得记上这一次。

解法:

class Solution:
    def trailingZeroes(self, n: int) -> int:
		# 非递归
        res = 0
        while n > 0:
            n //= 5
            res += n
        return res

        # # 递归
        # if n == 0:
        #     return 0
        # else:
        #     return self.trailingZeroes(n // 5) + n // 5

189. 旋转数组

题目:

5 lenet 代码python leetcode5 python_子串_03


思路:

1.最直接的方法就是按照题意读取最后一个值,如果插入第一个位置;
2.反转法,先反转整个数组,再反转前k个数,再反转剩下的数;

解法:

  • 直接求解
class Solution:
    def rotate(self, nums: List[int], k: int) -> None:
        """
        Do not return anything, modify nums in-place instead.
        """
        # # 暴力破解  
        for i in range(k):
            num = nums.pop()
            nums.insert(0, num)
  • 反转法
class Solution:
    def rotate(self, nums: List[int], k: int) -> None:
        """
        Do not return anything, modify nums in-place instead.
        """
        # 反转法
        l = len(nums)
        k = k % n
        if n < 2:
            pass
        else:
            def reverse(nums, t, s):
                while t < s:
                    nums[t], nums[s] = nums[s], nums[t]
                    t += 1
                    s -= 1
            reverse(nums, 0, n-1)
            reverse(nums, 0, k-1)
            reverse(nums, k, n-1)

中等题

2. 两数相加

题目:

5 lenet 代码python leetcode5 python_链表_04


思路:

创建一个新的链表,每一个结点相加后将个位数入栈,用carry表示十位数是否进位,依次遍历给定链表,可以获得目标链表。

解法:

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    def addTwoNumbers(self, l1: ListNode, l2: ListNode) -> ListNode:

        carry = 0
        res = ListNode(0)
        cur = res

        while l1 or l2: 

            val_1 = l1.val if l1 else 0
            val_2 = l2.val if l2 else 0
            val_sum = val_1 + val_2 + carry

            carry = val_sum // 10
            cur.next = ListNode(val_sum % 10)

            cur = cur.next                  
            if l1:                         
                l1 = l1.next
            if l2:
                l2 = l2.next

        if carry > 0:                       
            cur.next = ListNode(carry)

        return res.next

3. 无重复字符的最长子串

题目:

5 lenet 代码python leetcode5 python_5 lenet 代码python_05

思路:

遍历字符串,当字母不存在与子串中,加入子串。当字母存在于子串中,查找子串中这个字母的位置,子串变为这个字母之后的切片。

解法:

class Solution:
    def lengthOfLongestSubstring(self, s: str) -> int:

        # 如果是空,返回0
        if not s:
            return 0

        # 初始化参数
        sub_sring = ""
        sub_len = 0
        max_len = 0

        for c in s:
            
            # 当字母已经存在了,回溯到前一个相同字母的位置
            if c in sub_sring:
                sub_sring = sub_sring[sub_sring.index(c) + 1:]
                sub_len = len(sub_sring)

            sub_sring += c
            sub_len += 1

            if sub_len >= max_len:
                max_len = sub_len
            
        return max_len

5. 最长回文子串

题目:

5 lenet 代码python leetcode5 python_链表_06

思路:

尝试了各种写法,还是暴力破解舒服

解法:

class Solution:
    def longestPalindrome(self, s: str) -> str:

        for l in range(len(s), -1, -1):

            for i in range(0, len(s) - l + 1):

                sub_string = s[i:l + i]

                if sub_string == sub_string[::-1]:
                    
                    return sub_string

6. Z 字形变换

题目:

5 lenet 代码python leetcode5 python_子串_07


5 lenet 代码python leetcode5 python_5 lenet 代码python_08

思路:

Z字形走动,可以使用一个flag来判别行走的方向。

解法:

class Solution:
    def convert(self, s: str, numRows: int) -> str:

        if numRows < 2: 
            return s

        res = ["" for _ in range(numRows)]
        i, flag = 0, -1

        # flag 表示方向
        for c in s:
            res[i] += c
            if i == 0 or i == numRows - 1: 
                flag = -flag
            i += flag
        return "".join(res)

8. 字符串转换整数 (atoi)

题目:

5 lenet 代码python leetcode5 python_子串_09


5 lenet 代码python leetcode5 python_python_10

思路:

遍历判断。

解法:

class Solution:
    def myAtoi(self, str: str) -> int:

        # 去除首尾的空格
        str = str.strip()

        if not str: 
            return 0

        result = ''
        flag = 1

        # 遍历判断符号与数字
        for i in range(len(str)):
            if i == 0:
                if str[i] not in ['+', '-'] and not str[i].isdigit():
                    return 0
                if str[i] == '-':
                    flag = -1
                elif str[i] == '+':
                    flag = 1
                else:
                    result += str[i]
            elif not str[i].isdigit():
                break
            else:
                result += str[i]
        if  result:
            if -2 ** 31 <= int(result) * flag <= 2 **31 - 1: 
                return int(result) * flag
            elif flag == -1:
                return - 2 ** 31
            else:
                return 2 ** 31 -1
        else:
            return 0