益智小游戏 Python 二

本笔记的题目参考自leetcode

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

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

class Solution:
    def findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float:
        for i in nums2:
            nums1.append(i)
        nums1.sort()

        if len(nums1) % 2 != 0:
            return(float(nums1[int((len(nums1)-1)/2)]))
        else:
            return(float((nums1[int(len(nums1)/2)]+nums1[int(len(nums1)/2-1)])/2))

执行用时:56 ms, 在所有 Python3 提交中击败了52.74%的用户
内存消耗:15 MB, 在所有 Python3 提交中击败了14.23%的用户

5、最长回文子串

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

自己的解法:暴力解法

时间复杂度应该为:构建所有的子串 + 从中间向外扩散遍历子串 O(n!*n)

空间复杂度应该为:构建所有的子串起始点重点的数组个数:O(2n!)

class Solution:
    def substring(self, s):
        # 子串长度循环1--len(s)
        num = []
        for i in reversed(range(1, len(s)+1)):
            # 子串起点循环0--len(s)-i+1
            for j in range(0, len(s)-i+1): 
                # num.append(s[j: j+i])
                num.append([j, j+i])
        return num
    
    def distin(self, s):
        # 奇偶数区别
        if len(s)%2 == 0:
            # 从中间向两边遍历判断对称位置是否相等
            for i in range(int(len(s)/2)):
                if s[int(len(s)/2)+i] != s[int(len(s)/2)-1-i]:
                    return False
            return True
        else:
            for i in range(1, int((len(s)-1)/2)+1):
                if s[int((len(s)-1)/2)+i] != s[int((len(s)-1)/2)-i]:
                    return False
            return True

    def longestPalindrome(self, s: str) -> str:
        if len(s) < 2:
            return s
        else:
            for num in self.substring(s):
                if self.distin(s[num[0]:num[1]]):
                    return s[num[0]:num[1]]

orz!
在这里插入图片描述

答案解法一:

其思想主要也是暴力解法,值得借鉴的地方是代码里体现了迭代思想,代码抽象了很多,看起来比自己的代码简洁多了。但是复制过去还是执行超时哎!

class Solution:
    def longestPalindrome(self, 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

在这里插入图片描述
在这里插入图片描述
再琢磨一下,完全搞明白之后再复现一遍

在这里插入图片描述

解法二

很好理解,但是需要仔细想一下为什么这么做速度快

class Solution:
    def expandAroundCenter(self, s, left, right):
        while left >= 0 and right < len(s) and s[left] == s[right]:
            left -= 1
            right += 1
        return left + 1, right - 1

    def longestPalindrome(self, s: str) -> str:
        start, end = 0, 0
        for i in range(len(s)):
            left1, right1 = self.expandAroundCenter(s, i, i)
            left2, right2 = self.expandAroundCenter(s, i, i + 1)
            if right1 - left1 > end - start:
                start, end = left1, right1
            if right2 - left2 > end - start:
                start, end = left2, right2
        return s[start: end + 1]

时间复杂度:O(n^2)
),其中 n 是字符串的长度。长度为 1和 2 的回文中心分别有 n 和n−1 个,每个回文中心最多会向外扩展 O(n)次。

空间复杂度:O(1)

6、z形变换

这一题自己在思考的时候一直在思考使用什么格式去保存字符
百思不得其解,最后才发现答案使用的是列表和字符串,真的太巧妙了

class Solution:
     def convert(self, s: str, numRows: int) -> str:
        if  numRows < 2:
            return s
        res = ["" for _ in range(numRows)]
        i, flag = 0, -1
        for c in s:
            res[i] += c
            if i == 0 or i == numRows - 1: flag = -flag
            i += flag
        return "".join(res)

猜你喜欢

转载自blog.csdn.net/Winds_Up/article/details/112707895