LeetCode刷题修炼

小白的LeetCode刷题修炼【python】(1)

LeetCode是一个非常不错的刷题平台,用过的都知道😎,对于像我这样的小白来说里面的题目有点也还算可以,最优势的是你可以看见很多非常不错的刷题思路和方法。
这里我刚刚开刷,每个题目都会自己写一写(没啥参考价值的就不献丑了😁),【5个一组,毕竟不太好写😢】,对于解决方法较好的思路我也会分享给大家,大家也可以在一起讨论,总之各位加油吧!

1.两数之和

给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出和为目标值的那两个整数,并返回它们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素不能使用两遍。你可以按任意顺序返回答案

#答案:
class Soultion:
    def twoSum(self,nums,target):
        for i in range(len(nums)):
            for j in range(i+1,len(nums)):
                if nums[i]+nums[j] == target:
                    return [i,j]
print(Soultion.twoSum([3,3],6))
#较好的答案
class Solution:
    def twoSum(self,nums, target):
        hashmap = {}
        for index, num in enumerate(nums):
            another_num = target - num
            if another_num in hashmap:
                return [hashmap[another_num], index]
            hashmap[num] = index
print(Soultion.twoSum([3,3],6))
#转载处:LeetCode
#作者:magiczsd
#链接:https://leetcode-cn.com/problems/two-sum/solution/hao-shi-12mszai-suo-you-python-ti-jiao-z-5bch/

2.两数相加

给你两个非空的链表,表示两个非负的整数。它们每位数字都是按照逆序的方式存储的,并且每个节点只能存储一位数字。
请你将两个数相加,并以相同形式返回一个表示和的链表。你可以假设除了数字 0 之外,这两个数都不会以 0 开头。

#答案
class Solution(object):
    def addTwoNumbers(self, l1, l2):
        if len(l1) < len(l2):
            for i in range(len(l2)-len(l1)):
                l1.append(0)
        if len(l1) > len(l2):
            for i in range(len(l1)-len(l2)):
                l2.append(0)
        a = [str(i) for i in l1]
        b = ''.join(a)[::-1]
        A = int(b)
        c = [str(i) for i in l2]
        d = ''.join(c)[::-1]
        B = int(d)
        num = A+B
        res = str(num)[::-1]
        e = list(res)
        result = [int(i) for i in e]
        return result
print(Solution().addTwoNumbers([9,9,9,9,9,9,9],[9,9,9,9]))
#转载处:LeetCode
#作者:dnanki
#链接:https://leetcode-cn.com/problems/add-two-numbers/solution/di-gui-si-lu-jian-dan-dai-ma-duan-by-dnanki/

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

给定一个字符串,请你找出其中不含有重复字符的最长子串的长度

#答案
class Solution:
    def lengthOfLongestSubstring(s: str) -> int:
        n = len(s)
        longest = 0
        end = -1
        dic = {}
        for i, c in enumerate(s):
            if c in dic:
                end = max(end, dic[c])
            longest = max(longest, i - end)
            dic[c] = i
        return longest
print(Solution.lengthOfLongestSubstring('pwwkew'))
#转载处:LeetCode
#作者:AIResearcherJHM
#链接:https://leetcode-cn.com/problems/longest-substring-without-repeating-characters/solution/python3zi-dian-ji-lu-mei-ge-zi-fu-zui-hou-chu-xian/

4. 寻找两个正序数组的中位数

给定两个大小为 m 和 n 的正序(从小到大)数组 nums1nums2。请你找出并返回这两个正序数组的中位数。

#答案
class Solution:
    def findMedianSortedArrays(nums1,nums2):
        num =(nums1+nums2)
        l = len(num)
        if l%2 == 0:
            mid = float(num[l//2]+num[l//2-1])/2
        else:
            mid = float(num[l//2])
        return mid
print(Solution.findMedianSortedArrays([3,5],[2,4]))
#较好的答案
class Solution:
    def findMedianSortedArrays(nums1: List[int], nums2: List[int]) -> float:
        def getKthElement(k):          
            index1, index2 = 0, 0
            while True:
                # 特殊情况
                if index1 == m:
                    return nums2[index2 + k - 1]
                if index2 == n:
                    return nums1[index1 + k - 1]
                if k == 1:
                    return min(nums1[index1], nums2[index2])

                # 正常情况
                newIndex1 = min(index1 + k // 2 - 1, m - 1)
                newIndex2 = min(index2 + k // 2 - 1, n - 1)
                pivot1, pivot2 = nums1[newIndex1], nums2[newIndex2]
                if pivot1 <= pivot2:
                    k -= newIndex1 - index1 + 1
                    index1 = newIndex1 + 1
                else:
                    k -= newIndex2 - index2 + 1
                    index2 = newIndex2 + 1
        
        m, n = len(nums1), len(nums2)
        totalLength = m + n
        if totalLength % 2 == 1:
            return getKthElement((totalLength + 1) // 2)
        else:
            return (getKthElement(totalLength // 2) + getKthElement(totalLength // 2 + 1)) / 2
print(Solution.findMedianSortedArrays([3,5],[2,4]))
#转载处:LeetCode
#作者:LeetCode-Solution
#链接:https://leetcode-cn.com/problems/median-of-two-sorted-arrays/solution/xun-zhao-liang-ge-you-xu-shu-zu-de-zhong-wei-s-114/

较好的方法的解题思路:

假设两个有序数组分别是A 和 B。要找到第 k 个元素,我们可以比较 A[k/2−1] 和 B[k/2−1],其中 //表示整数除法。由于A[k/2−1]和 B[k/2−1] 的前面分别有A[0…k/2−2] 和B[0…k/2−2],即 k/2−1 个元素,对于 A[k/2−1] 和 B[k/2−1] 中的较小值,最多只会有 2(k/2−1)+(k/2−1)≤k−2 个元素比它小,那么它就不能是第 k小的数了。

因此我们可以归纳出三种情况:

  • 如果 A[k/2−1]<B[k/2−1],则比 A[k/2−1] 小的数最多只有 A 的前 k/2−1 个数和B 的前k/2−1个数,即比 A[k/2−1] 小的数最多只有 k−2 个,因此 A[k/2−1] 不可能是第 k 个数,A[0] 到 A[k/2−1] 也都不可能是第 k 个数,可以全部排除。

  • 如果A[k/2−1]>B[k/2−1],则可以排除B[0] 到 B[k/2−1]。

  • 如果 A[k/2−1]=B[k/2−1],则可以归入第一种情况处理。

可以看到,比较A[k/2−1] 和 B[k/2−1] 之后,可以排除 k/2 个不可能是第 k 小的数,查找范围缩小了一半。同时,我们将在排除后的新数组上继续进行二分查找,并且根据我们排除数的个数,减少 k 的值,这是因为我们排除的数都不大于第 k 小的数。

有以下三种情况需要特殊处理:

  • 如果 A[k/2−1] 或者 B[k/2−1] 越界,那么我们可以选取对应数组中的最后一个元素。在这种情况下,我们必须根据排除数的个数减少 k 的值,而不能直接将 k 减去k/2。

  • 如果一个数组为空,说明该数组中的所有元素都被排除,我们可以直接返回另一个数组中第 k 小的元素。

  • 如果k=1,我们只要返回两个数组首元素的最小值即可。

5. 最长回文子串

给你一个字符串 s,找到 s 中最长的回文子串。

#答案
class Solution:
    def longestPalindrome(s: str) -> str:
        n = len(s)
        dp = [[False] * n for _ in range(n)]
        ans = ""
        # 枚举子串的长度 l+1
        for l in range(n):
            # 枚举子串的起始位置 i,这样可以通过 j=i+l 得到子串的结束位置
            for i in range(n):
                j = i + l
                if j >= len(s):
                    break
                if l == 0:
                    dp[i][j] = True
                elif l == 1:
                    dp[i][j] = (s[i] == s[j])
                else:
                    dp[i][j] = (dp[i + 1][j - 1] and s[i] == s[j])
                if dp[i][j] and l + 1 > len(ans):
                    ans = s[i:j+1]
        return ans
print(Solution.longestPalindrome('ababd'))
#转载处:LeetCode
#作者:LeetCode-Solution
#链接:https://leetcode-cn.com/problems/longest-palindromic-substring/solution/zui-chang-hui-wen-zi-chuan-by-leetcode-solution/
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值