leetcode

# 最长回文子串
class Solution:
    def longestPalindrome(self, s: str) -> str:
        return self.manacher(s)

    @staticmethod
    def manacher(s: str) -> str:
        # 如果s是单字符的字符串,那么直接返回
        if len(s) < 2:
            return s

        # 将一个可能是偶数长/奇数长的字符串,首位以及每个字符间添加#,确保添加后变成了长度为奇数的字符串
        manacher_length = len(s) * 2 + 1
        manacher_str = "#".join(s).center(manacher_length, "#")

        # 记录最长子回文串
        max_palindrome = ""
        for i in range(manacher_length):
            left = i - 1
            right = i + 1
            while left >= 0 and right < manacher_length and \
                    manacher_str[left] == manacher_str[right]:
                left -= 1
                right += 1

            # 将左右指针回退一位,得到本次遍历的回文串长度:(right - 1) - (left + 1) + 1 = right - left - 1
            if right - left - 1 > len(max_palindrome):
                max_palindrome = manacher_str[left + 1:right]

        # 由于max_palindrom是包含特殊字符#的回文子串,因此需要将#字符删除后返回
        return max_palindrome.replace("#", "")

# 自测用例
if __name__ == '__main__':
    s = Solution()
    result = s.longestPalindrome("abcbcba")
    print(result)
# 最长无重复子串
def longest_str(str):
    str_dict = {}
    start = 0
    res = ""
    for i in range(len(str)):
        if str[i] in str_dict:
            start = max(start, str_dict[str[i]] + 1)
        str_dict[str[i]] = i
        if len(str[start:i+1])>len(res):
            res = str[start:i+1]
    return res
print(longest_str("abcdcabcde"))
# 最大子数组和
def max_sum(arr):
    dp = [0] * len(arr)
    dp[0] = arr[0]
    for i in range(1, len(arr)):
        dp[i] = max(arr[i], dp[i-1]+arr[i])
    return max(dp)
# 最大子数组乘积
def max_multi(arr):
    dp_max = [0]*len(arr)
    dp_min = [0]*len(arr)
    dp_max[0] = arr[0]
    dp_min[0] = arr[0]
    for i in range(1,len(arr)):
        dp_min[i] = min(arr[i], arr[i]*dp_min[i-1])
        dp_max[i] = max(arr[i], arr[i]*dp_max[i-1], arr[i]*dp_min[i-1])
    return max(dp_max)
print(max_multi([2,3,-2,4]))
# 组合总和
class Solution:
    def combinationSum(self, candidates, target):
        result = []
        self.DFS(candidates, [], target,result)
        return result

    def DFS(self,candidates, path, target,result):
        # 不符合,结束
        if sum(path)>target:
            return

        # 这是DFS的边界控制条件,当 路径和等于目标时,说明这个路径是我们所需要的。直接附加到结果即可。
        if sum(path) == target:
            result.append(path[:])
            return

        # 相同的套路,对DFS下的所有路径进行遍历呗,进行往path路径上的附加。
        for i in range(len(candidates)):
            # 如果dfs的是candidates的话,就是全排列
            # 如果从index开始的数组,即下一次dfs是从他自己开始,就是去重复的数组,就是前边考虑过的数,不再考虑了
            # 如果从index+1开始的话,就是没有重复数字的去重数组
            path.append(candidates[i])
            self.DFS(candidates[i:], path,target,result)
            # 在DFS递归最后,进行一定的还原
            path.pop()
aa = Solution()
print(aa.combinationSum([2,3,6,7], 7))
# 组合
class Solution:
    #主函数,这里会启动DFS的 组合搜索
    def permute(self, nums):
        result=[]
        l=len(nums)
        self.DFS(nums,[],result,l)
        return result
    #
    def DFS(self,nums,path,result,l):
        #这是  拼接成功的  标识,当拼接成功时,说明是一个成功的 DFS遍历得到的结果。 path中存储中的当做真实的拼接来用即可。
        if len(path)==l:
            result.append(path[:])
            return

        #这里是针对数组 进行拼接角度的DFS遍历
        for i in range(len(nums)):
            path.append(nums[i])
            self.DFS(nums[:i]+nums[i+1:],path,result,l)
            #DFS最核心的一点是 一定要进行还原,这样才能轻量化,path内的信息才是每次构建时所需要的。
            path.pop()
aa = Solution()
print(aa.permute([2,3,6]))
def quick_sort(alist, start, end):
    """快速排序"""
    if start >= end:  # 递归的退出条件
        return
    mid = alist[start]  # 设定起始的基准元素
    low = start  # low为序列左边在开始位置的由左向右移动的游标
    high = end  # high为序列右边末尾位置的由右向左移动的游标
    while low < high:
        # 如果low与high未重合,high(右边)指向的元素大于等于基准元素,则high向左移动
        while low < high and alist[high] >= mid:
            high -= 1
        alist[low] = alist[high]  # 走到此位置时high指向一个比基准元素小的元素,将high指向的元素放到low的位置上,此时high指向的位置空着,接下来移动low找到符合条件的元素放在此处
        # 如果low与high未重合,low指向的元素比基准元素小,则low向右移动
        while low < high and alist[low] < mid:
            low += 1
        alist[high] = alist[low]  # 此时low指向一个比基准元素大的元素,将low指向的元素放到high空着的位置上,此时low指向的位置空着,之后进行下一次循环,将high找到符合条件的元素填到此处

    # 退出循环后,low与high重合,此时所指位置为基准元素的正确位置,左边的元素都比基准元素小,右边的元素都比基准元素大
    alist[low] = mid  # 将基准元素放到该位置,
    # 对基准元素左边的子序列进行快速排序
    quick_sort(alist, start, low - 1)  # start :0  low -1 原基准元素靠左边一位
    # 对基准元素右边的子序列进行快速排序
    quick_sort(alist, low + 1, end)  # low+1 : 原基准元素靠右一位  end: 最后



if __name__ == '__main__':
    alist = [54, 26, 93, 17, 77, 31, 44, 55, 20]
    quick_sort(alist, 0, len(alist) - 1)
    print(alist)

  

  

  

  

  

  

posted @ 2023-08-21 16:46  15375357604  阅读(5)  评论(0编辑  收藏  举报