【leetcode刷题】50题(11-20题)

 

 

88. 合并两个有序数组
给你两个有序整数数组 nums1 和 nums2,请你将 nums2 合并到 nums1 中,使 num1 成为一个有序数组。

class Solution:
    def merge(self, nums1: List[int], m: int, nums2: List[int], n: int) -> None:
        """
        Do not return anything, modify nums1 in-place instead.
        """
        # 方法1:技巧合并
        # nums1[:] = nums1[:len(nums1)-n] + nums2
        # nums1.sort()

        # 方法2:双指针:从后往前
        p1, p2 = m-1, n-1
        p = m+n-1
        while p1 >= 0 and p2 >= 0:
            if nums1[p1] < nums2[p2]:
                nums1[p] = nums2[p2]
                p2 -= 1
            else:
                nums1[p] = nums1[p1]
                p1 -= 1
            p=p-1
        nums1[:p2+1] = nums2[:p2+1]

14. 最长公共前缀

class Solution:
    def longestCommonPrefix(self, strs: List[str]) -> str:
        # 方法一:zip()+set()
        # s = ""
        # for i in zip(*strs):
        #     if len(set(i)) == 1:
        #         s= s+i[0]
        #     else:
        #         break
        # return s

        # 方法二:遍历
        if len(strs) == 0:
            return ''
        for i in range(len(strs[0])):
            c = strs[0][i]
            for j in range(1,len(strs)):
                if i == len(strs[j]) or strs[j][i] != c:
                    return strs[0][0:i]
        return strs[0]

        # 遍历
        if len(strs)==0:return ""
        tmp = ""
        for i in range(len(strs[0])):
            for j in range(1, len(strs)):
                if len(strs[j]) == i or strs[0][i] != strs[j][i]:
                    return tmp
            tmp = tmp + strs[0][i]
        return tmp

118. 杨辉三角

给定一个非负整数 numRows,生成杨辉三角的前 numRows 行。

在杨辉三角中,每个数是它左上方和右上方的数的和。

class Solution:
    def generate(self, numRows: int) -> List[List[int]]:
        # 取巧:上下行加1
        # if numRows == 0: return []
        # if numRows == 1: return [[1]]
        # res = [[1]]
        # for i in range(2, numRows+1):
        #     new_row = [a+b for a,b in zip([0]+ res[-1], res[-1]+[0])]
        #     res.append(new_row)
        # return res

        # 递归
        if numRows == 0:return []
        if numRows == 1: return [[1]]
        upper = self.generate(numRows - 1)
        new_row = [1]
        for i in range(1, numRows-1):
            new_row.append(upper[-1][i-1]+upper[-1][i])
        new_row.append(1)
        upper.append(new_row)
        return upper

        #动态
        # dp = [[1]*i for i in range(1, numRows+1)]
        # for i in range(numRows):
        #     for j in range(1, i):
        #         dp[i][j] = dp[i-1][j-1]+dp[i-1][j]
        # return dp

13. 罗马数字转整数

class Solution:
    def romanToInt(self, s: str) -> int:
        roman_dict = {
            "I":"1",
            "V":"5",
            "X":"10",
            "L":"50",
            "C":"100",
            "D":"500",
            "M":"1000",
            "IV":"4",
            "IX":"9",
            "XL":"40",
            "XC":"90",
            "CD":"400",
            "CM":"900"
            }
        nums = 0

        for i in range(len(s)-1):
            if int(roman_dict[s[i]]) < int(roman_dict[s[i+1]]):
                nums = nums - int(roman_dict[s[i]])
            else:
                nums = nums + int(roman_dict[s[i]])
        nums = nums + int(roman_dict[s[-1]])
        return nums

28. 实现 strStr()

实现 strStr() 函数。

给定一个 haystack 字符串和一个 needle 字符串,在 haystack 字符串中找出 needle 字符串出现的第一个位置 (从0开始)。如果不存在,则返回  -1

class Solution:
    def strStr(self, haystack: str, needle: str) -> int:
        # 方法1:find
        # return haystack.find(needle)

        # 方法2:split
        # if needle == "":return 0
        # if needle in haystack:
        #     li = haystack.split(needle)
        #     return len(li[0])
        # else:
        #     return -1

        # 方法三:双指针
        i, j = 0, 0
        tmp = -1
        if needle == "":return 0
        while j < len(needle) and i < len(haystack):
            if haystack[i] == needle[j]:
                if j == 0:tmp = i
                i += 1
                j += 1
            elif j != 0:
                i, j = tmp+1, 0
                tmp = -1
            else:
                i += 1
                j,tmp = 0,-1
        if j == len(needle):return tmp
        return -1

26. 删除排序数组中的重复项

给定一个排序数组,你需要在 原地 删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度。

不要使用额外的数组空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。

class Solution:
    def removeDuplicates(self, nums: List[int]) -> int:
        # 方法一:for循环,逆序
        # for i in range(len(nums)-1, 0, -1):
        #     if nums[i-1]==nums[i]:
        #         nums.pop(i)
        # return len(nums)

        # 方法二:“”占位,正序
        for i in range(len(nums)-1):
            if nums[i] == nums[i+1]:
                nums[i] = ""
        while "" in nums:
            nums.remove("")

189. 旋转数组

给定一个数组,将数组中的元素向右移动 个位置,其中 是非负数。

class Solution:
    def rotate(self, nums: List[int], k: int) -> None:
        """
        Do not return anything, modify nums in-place instead.
        """
        # 方法一:切片
        # k = k % len(nums)
        # nums[:] = nums[-k:] + nums[:-k]

        #方法二:三次反转
        k = k % len(nums)
        nums[:] = nums[::-1]
        nums[:k] = nums[:k][::-1]
        nums[k:] = nums[k:][::-1]

69. x 的平方根

实现 int sqrt(int x) 函数。

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

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

class Solution:
    def mySqrt(self, x: int) -> int:
        # 二分查找
        if x < 1:return 0
        if x < 4:return 1
        l, r = 0, x//2
        while l <= r:
            mid = (r+l)//2
            if mid*mid < x:
                l=mid+1
            elif mid*mid > x:
                r=mid-1
            else:
                return mid
        return r

66. 加一

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

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

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

class Solution:
    def plusOne(self, digits: List[int]) -> List[int]:
        # 数学法:
        # 从最后一个元素开始遍历到底1个元素
        for i in range(len(digits)-1,-1,-1):
            # 如果该元素不是9,则该元素加1,返回结果
            if digits[i] != 9:
                digits[i] = digits[i]+1
                return digits
            # 如果该元素是9,则该元素变为0,遍历前一个元素,直至遍历到非9的元素
            digits[i] = 0
        # 如果第1个元素是0,说明是999类似的数值,则在最前面插入1
        if digits[0] == 0:
            digits.insert(0,1)
            return digits


        # 暴力法:
        # 将int转为str,再join拼接
        # num = int("".join([str(i) for i in digits])) + 1
        # return [int(x) for x in str(num)]

125. 验证回文串

给定一个字符串,验证它是否是回文串,只考虑字母和数字字符,可以忽略字母的大小写。

说明:本题中,我们将空字符串定义为有效的回文串。

class Solution:
    def isPalindrome(self, s: str) -> bool:
        # pattern = r'[a-zA-Z0-9]'
        # res = re.findall(pattern, s)
        # res = ''.join(res).lower()
        # return res == res[::-1]

        s = ''.join(e for e in s if e.isalnum()).lower()
        return s==s[::-1]

415. 字符串相加

给定两个字符串形式的非负整数 num1 和num2 ,计算它们的和。

注意:

  1. num1 和num2 的长度都小于 5100.
  2. num1 和num2 都只包含数字 0-9.
  3. num1 和num2 都不包含任何前导零。
  4. 你不能使用任何內建 BigInteger 库, 也不能直接将输入的字符串转换为整数形式。
    class Solution:
        def addStrings(self, num1: str, num2: str) -> str:
            i, j = len(num1)-1, len(num2)-1
            carry, res = 0, ""
            while i >= 0 or j >= 0:
                if i>=0:
                    carry += int(num1[i])
                    i -= 1
                if j >=0:
                    carry += int(num2[j])
                    j -= 1
                res = str(carry%10)+res
                carry //= 10
            if carry != 0:return "1"+res
            return res

LCP 1. 猜数字

小A 和 小B 在玩猜数字。小B 每次从 1, 2, 3 中随机选择一个,小A 每次也从 1, 2, 3 中选择一个猜。他们一共进行三次这个游戏,请返回 小A 猜对了几次?

输入的guess数组为 小A 每次的猜测,answer数组为 小B 每次的选择。guessanswer的长度都等于3。

class Solution:
    def game(self, guess: List[int], answer: List[int]) -> int:
        # guess = [1, 2, 3], answer = [1, 2, 3]
        n = 0
        for i in range(len(guess)):
            a = guess[i]
            b = answer[i]
            if a == b:
                n += 1
        n=str(n)
        return n

509. 斐波那契数

斐波那契数,通常用 F(n) 表示,形成的序列称为斐波那契数列。该数列由 0 和 1 开始,后面的每一项数字都是前面两项数字的和。也就是:

F(0) = 0,   F(1) = 1
F(N) = F(N - 1) + F(N - 2), 其中 N > 1.

给定 N,计算 F(N)

class Solution:
    def fib(self, N: int) -> int:
        # 动态
        if N <= 1:
            return N
        a, b = 0, 1
        for i in range(2, N+1):
            a, b = b, a+b
        return b

        # # 递归
        # if N <= 1:
        #     return N
        # return self.fib(N-1) + self.fib(N-2)

704. 二分查找

给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target  ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1

class Solution:
    def search(self, nums: List[int], target: int) -> int:
        # 暴力法
        # if target in nums: return nums.index(target)
        # return -1

        # 二分查找法1
        # left, right = 0, len(nums)-1
        # while (left <= right):
        #     mid = (right + left)//2
        #     if nums[mid] == target:
        #         return mid
        #     elif nums[mid] < target:
        #         left = mid + 1
        #     else:
        #         right = mid - 1
        # return -1

101. 对称二叉树

给定一个二叉树,检查它是否是镜像对称的。

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution:
    def isSymmetric(self, root: TreeNode) -> bool:
        #递归:
        if root == None:return True
        def match(l,r):
            if l == None and r==None:return True
            elif l == None or r ==None:return False
            elif l.val != r.val:return False
            return match(l.left, r.right) and match(l.right, r.left)
        
        return match(root.left, root.right)

104. 二叉树的最大深度

给定一个二叉树,找出其最大深度。

二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。

说明: 叶子节点是指没有子节点的节点。

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution:
    def maxDepth(self, root: TreeNode) -> int:
        # 递归
        # if root == None:return 0
        # return 1 + max(self.maxDepth(root.left), self.maxDepth(root.right))

        # 迭代
        stack = []
        if root is not None:stack.append((1, root))
        depth = 0
        while stack != []:
            current_depth, root = stack.pop()
            if root is not None:
                depth = max(depth, current_depth)
                stack.append((current_depth+1,root.left))
                stack.append((current_depth+1,root.right))
        return depth

976. 三角形的最大周长

给定由一些正数(代表长度)组成的数组 A,返回由其中三个长度组成的、面积不为零的三角形的最大周长。

如果不能形成任何面积不为零的三角形,返回 0

class Solution:
    def largestPerimeter(self, A: List[int]) -> int:
        if 3 <= len(A):
            A = sorted(A, reverse = True)
            for i in range(0,len(A)-2):
                if A[i] < A[i+1] + A[i+2]:
                    return A[i]+A[i+1]+A[i+2]
            return 0
        return 0

35. 搜索插入位置

给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。

你可以假设数组中无重复元素。

class Solution:
    def searchInsert(self, nums: List[int], target: int) -> int:
        # 暴力法1
        # if target in nums:return nums.index(target)
        # i = 0
        # while i < len(nums):
        #     if nums[i] < target:
        #         i +=1
        #     else:
        #         break
        # return i

        # 暴力法2
        if target in nums:return nums.index(target)
        for i in range(len(nums)):
            if nums[i] > target:
                return i
        return i+1

        # 二分法
        # 因为有可能数组的最后一个元素的位置的下一个是我们要找的,故右边界是 len
        # left, right = 0, len(nums)
        # while (left < right):
        #     mid = (left + right)//2
        #     # 严格小于 target 的元素一定不是解
        #     if nums[mid] == target:
        #         # 下一轮搜索区间是 [mid + 1, right]
        #         return mid
        #     elif nums[mid] < target:
        #         left = mid + 1
        #     else:
        #         right = mid
        # return left

        # 技巧法
        # nums.append(target)
        # nums.sort()
        # return nums.index(target)

989. 数组形式的整数加法

对于非负整数 X 而言,X 的数组形式是每位数字按从左到右的顺序形成的数组。例如,如果 X = 1231,那么其数组形式为 [1,2,3,1]

给定非负整数 X 的数组形式 A,返回整数 X+K 的数组形式。

class Solution:
    def addToArrayForm(self, A: List[int], K: int) -> List[int]:
        # # 1、暴力法,转化为整数
        # s = ""
        # for i in A:
        #     s = s + str(i)
        # num = int(s) + K
        # return [int(j) for j in str(num)]

        # 方法二:遍历元素求和
        K_li = [int(i) for i in str(K)]
        i, j = len(A)-1, len(K_li)-1
        carry, res = 0, []
        while i>=0 or j>=0:
            if i>=0:
                carry += A[i]
                i -= 1
            if j>=0:
                carry += K_li[j]
                j -=1
            res = [carry%10] + res
            carry //= 10
        if carry != 0:return [1]+res
        return res

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值