• 编程之法之字符串


    字符串

    1.1 字符串的旋转

    (leetcode 796) 给定两个字符串, A 和 B。A 的旋转操作就是将 A 最左边的字符移动到最右边。 例如, 若 A = 'abcde',在移动一次之后结果就是'bcdea' 。如果在若干次旋转操作之后,A 能变成B,那么返回True。
    :主要需要考虑为空的情况,另外就是当num超过字符串长度

    class Solution:
        def rotateString(self, A: str, B: str) -> bool:
            if not A and not B:
                return True
            if not A or not B:
                return False
            for i in range(len(A)+1):
                if B == self.rotate(A,i):
                    return True
            return False
        
        def rotate(self,A,num):
            indx = num%len(A)
            return A[indx:] + A[:indx]
    

    1.2 字符串的包含

    给定两个分别由字母组成的字符串A和字符串B,字符串B的长度比字符串A短。请问,如何最快地判断字符串B中所有字母是否都在字符串A里?

    def StringContain(strA,strB):
        strHash = 0
        for v in strA:
            strHash |= (1<<(ord(v)-ord('A'))
        for v in strB:
            if (strHash & (1 << (ord(v)-ord('A')))==0):
                return False
        return True
    

    1.3 字符串的全排列

    (leetcode 46) 给定一个没有重复数字的序列,返回其所有可能的全排列。

    class Solution:
        def permute(self, nums: List[int]) -> List[List[int]]:
            self.visited = [0] * len(nums)
            self.nums = nums
            self.result = []
            self.dfs([])
            return self.result
            
        def dfs(self,path):
            if len(path) == len(self.nums):
                self.result.append(path)
            else:
                for i in range(len(self.nums)):
                    if not self.visited[i]:
                        self.visited[i] = 1
                        self.dfs(path+[self.nums[i]])
                        self.visited[i] = 0
    

    第二种方法比第一种要慢

    class Solution:
        def permute(self, nums: List[int]) -> List[List[int]]:
            self.result = []
            self.perm(nums,0,len(nums))
            return self.result
    
        def perm(self,nums,fr,to):
            if to <= 1:
                self.result.append(nums)
                return
            if fr==to:
                tmp = nums[:]
                self.result.append(tmp)
            else:
                for i in range(fr,to):
                    nums[i],nums[fr] = nums[fr],nums[i]
                    self.perm(nums,fr+1,to)
                    nums[i],nums[fr] = nums[fr],nums[i]                
    

    1.3.1 字典序排列

    (leetcode 31) 下一个排列。
    实现获取下一个排列的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列。如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列)。
    注:这道题就是典型的字典序排列问题,过程如下:

    • 找到排列中最右边的一个升序首位位置i
    • 如果i小于0,说明找不到,则直接返回;
    • 找到排列中第i个位置右边最后一个比nums[i]大的位置j;
    • 交换i和j位置的数;
    • 把第i+1到最后的部分翻转;
    class Solution:
        def nextPermutation(self, nums: List[int]) -> None:
            """
            Do not return anything, modify nums in-place instead.
            """
            # 找到最后一个升序首位
            indx = -1
            for i in range(len(nums)-2,-1,-1):
                if nums[i] < nums[i+1]:
                    indx = i
                    break
            # 已经找到所有的
            if indx<0:
                nums.sort()
                return
            # 找到右边最后一个比nums_i大的位置
            k = len(nums)-1
            for k in range(len(nums)-1,indx,-1):
                if nums[k] > nums[indx]:
                    break
            nums[indx], nums[k] = nums[k], nums[indx]
            nums[indx+1:] = nums[indx+1:][::-1]
    

    1.4 回文判断

    (leetcode 234) 请判断一个链表是否为回文链表。
    这道题比较经典,涉及到如何使用快慢表,如何翻转链表;

    class Solution:
        def isPalindrome(self, head: ListNode) -> bool:
            slow = fast = head
            while fast and fast.next:
                slow = slow.next
                fast = fast.next.next
            new_head = None
            while slow:
                p = slow
                slow = slow.next
                p.next = new_head
                new_head = p
            while new_head:
                if new_head.val != head.val:
                    return False
                new_head = new_head.next
                head = head.next
            return True
    

    1.5 最长回文子串

    (leetcode 5) 最长回文子串
    注:注意对情况的讨论,第一种解法参考编程之法,原文中的代码在while语句中缺少边界判断,会报错。

    class Solution:
        def longestPalindrome(self, s: str) -> str:
            if not s:
                return s
            s = "#".join(s.strip())
            s = "#" + s + "#"
            p = [0]*len(s)
            mx = 0
            for i in range(1,len(s)):
                if mx > i:
                    p[i] = min(p[2*id-i],mx-i)
                else:
                    p[i] = 1
                while i+p[i] < len(s) and i-p[i] > 0 and (s[i+p[i]] == s[i-p[i]]):
                    p[i] += 1
                if p[i] + i > mx:
                    mx = p[i] + i
                    id = i
            l = max(p)-1
            indx = p.index(l+1)
            maxs = s[indx-l:indx+l+1]
            return "".join(maxs.split("#"))
    
    class Solution:
        def longestPalindrome(self, s: str) -> str:
            n = len(s)
            maxl = 0
            start = 0
            for i in range(n):
                if i-maxl >= 1 and s[i-maxl-1:i+1] == s[i-maxl-1:i+1][::-1]:
                    start = i - maxl - 1
                    maxl += 2
                    continue
                if i-maxl >= 0 and s[i-maxl:i+1] == s[i-maxl:i+1][::-1]:
                    start = i - maxl
                    maxl += 1
            return s[start:start+maxl]
    
  • 相关阅读:
    Open live Writer
    python两则99乘法表
    更改jupyter-notebook启动时的默认目录
    在内容中插入代码,返回进行编辑时,有无法跳出代码区的情况
    关于jupyter notebook密码设置
    nginx+zuul
    spring-cloud 服务优雅下线
    java.util.ConcurrentModificationException异常排查
    使用bitset实现毫秒级查询(二)
    使用bitset实现毫秒级查询
  • 原文地址:https://www.cnblogs.com/curtisxiao/p/11198435.html
Copyright © 2020-2023  润新知