day 5: 字符串

2023-05-16

1. 剑指 Offer 38. 字符串的排列

输入一个字符串,打印出该字符串中字符的所有排列。

你可以以任意顺序返回这个字符串数组,但里面不能有重复元素。

示例:

输入:s = "abc"
输出:["abc","acb","bac","bca","cab","cba"]

解法1. 递归

class Solution:
    def permutation(self, s: str) -> List[str]: 
        # # 字符串的全排列   
        result = []
        def perm(s_dir, one = ''):
            if s_dir:  
                buff = []  # 遍历所有字符,不处理 相同字符。 
                for i, x in enumerate(s_dir):
                    if x not in buff:
                        perm(s_dir[:i] + s_dir[i+1:], one+x)
                        buff.append(x)
            else:  # 找到最后, 相当于 叶子节点
                # if one not in result:  # 如果在这里判断,会超时
                result.append(one)
            return 
        perm(s)
        return result

2.  剑指 Offer 45. 把数组排成最小的数

输入一个非负整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。

示例 1:

输入: [10,2]
输出: "102"

示例 2:

输入: [3,30,34,5,9]
输出:"3033459"提示:

0 < nums.length <= 100
说明:

输出结果可能非常大,所以你需要返回一个字符串而不是整数
拼接起来的数字可能会有前导 0,最后结果不需要去掉前导 0

解法1:  快速排序

class Solution:
    def minNumber(self, nums: List[int]) -> str:
        # 本质上是个 排序 
        # 排序规则: x+y>y+x:  y小
        #          y+x > x +y, x小
        nums_str = [str(item) for item in nums]
        def one_sort(nums, start, end):
            # 一趟排序
            i = start
            j = end
            while i < j:
                # 从右往左扫描
                while i<j and nums[i] + nums[j] < nums[j] + nums[i]: 
                    j -= 1
                if i < j:
                    nums[i], nums[j] = nums[j], nums[i]
                    i = i + 1
                # 从左往右扫描
                while i < j and nums[i] + nums[j] < nums[j] + nums[i]: # 
                    i += 1
                if i < j:
                    nums[i], nums[j] = nums[j], nums[i]
                    j = j - 1
            return i
        # 快速排序算法 
        def quick_sort(nums, start, end):
            if start < end:
                p = one_sort(nums, start, end)
                # print(nums)
                quick_sort(nums, start, p-1)
                quick_sort(nums, p+1, end)
                
        quick_sort(nums_str, 0, len(nums_str)-1)

        return ''.join(nums_str)

3. 139. 单词拆分

给定一个非空字符串 s 和一个包含非空单词的列表 wordDict,判定 s 是否可以被空格拆分为一个或多个在字典中出现的单词。

说明:

拆分时可以重复使用字典中的单词。
你可以假设字典中没有重复的单词。

示例 1:

输入: s = "leetcode", wordDict = ["leet", "code"]
输出: true
解释: 返回 true 因为 "leetcode" 可以被拆分成 "leet code"。


示例 2:

输入: s = "applepenapple", wordDict = ["apple", "pen"]
输出: true
解释: 返回 true 因为 "applepenapple" 可以被拆分成 "apple pen apple"。
     注意你可以重复使用字典中的单词。

示例 3:

输入: s = "catsandog", wordDict = ["cats", "dog", "sand", "and", "cat"]
输出: false

解法1: 动态规划

class Solution:
    def wordBreak(self, s: str, wordDict: List[str]) -> bool:
        # 从s出发考虑, s中字符 划分后 是否都出现在wordDict
        # 采用 动态规划(不太熟练),遍历字符串;  很巧妙; 从字典开始匹配 递归超时
        dp = [0]*(len(s)+1) 
        dp[0] = 1
        for i in range(1, len(s)+1):
            for j in range(i):
                if dp[j] == 1 and s[j:i] in wordDict:
                    dp[i] = 1   # 从i 可以开始新的匹配了
                    break
        return dp[i] == 1

4. 140. 单词拆分 II

给定一个非空字符串 s 和一个包含非空单词列表的字典 wordDict,在字符串中增加空格来构建一个句子,使得句子中所有的单词都在词典中。返回所有这些可能的句子。

说明:

分隔时可以重复使用字典中的单词。
你可以假设字典中没有重复的单词。

示例:

输入:
s = "pineapplepenapple"
wordDict = ["apple", "pen", "applepen", "pine", "pineapple"]
输出:
[
  "pine apple pen apple",
  "pineapple pen apple",
  "pine applepen apple"
]
解释: 注意你可以重复使用字典中的单词。

 解法1:  递归 (超时)+ 投机取巧

class Solution:
    def wordBreak(self, s: str, wordDict: List[str]) -> List[str]:
        wordDict = sorted(wordDict)
        # any(): 可迭代对象中 若全为Fasle, 则返回False, 否则True;
        # all(): 可迭代对象中 若全为True,  则返回True, 否则Flase
        # 若想 句子中所有单词都在词典中, 句子中的 字母 必须都在 词典中出现的字符中;
        # 若 出现词典中 没出现过字符,则 必定不能组成句子; 
        if any([i not in set("".join(wordDict)) for i in s]):  # 全为False,any 返回false 
            return []   # 通过有点 投机取巧了;
        # 递归 超时 
        result = []
        def digui(s, wordDict, ju=''):
            if not s:
                result.append(ju.strip())
            for item in wordDict:
                item_len = len(item)
                if s[0:0+item_len] == item:  # 匹配成功
                    digui(s[0+item_len:], wordDict, ju + ' ' + item)
            return 
        digui(s, wordDict)
        return result

此题有个测试用例 很恶心:(去掉句子中b 依然超时)

"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
["a","aa","aaa","aaaa","aaaaa","aaaaaa","aaaaaaa","aaaaaaaa","aaaaaaaaa","aaaaaaaaaa"]

解法2:  从单词的角度去遍历, 也是投机取巧

class Solution:
    def wordBreak(self, s: str, wordDict: List[str]) -> List[str]:
        dp = [0]*(len(s)+1) 
        dp[0] = 1
        s_len = len(s)
        if not all([item in set(''.join(wordDict))    for item in s]):
            return []
        # 递归
        result = []
        def digui(s, wordDict, ss=''):  # 
            if not s:
                result.append(ss.strip())
            s_len = len(s)
            start = 0
            for i in range(s_len + 1):
                if s[start: start+i] in wordDict:
                    digui(s[start+i:], wordDict, ss + ' ' + s[start: start+i])
            return 
        digui(s, wordDict, '')
        return result

5. 20. 有效的括号

给定一个只包括 '(',')','{','}','[',']' 的字符串,判断字符串是否有效。

有效字符串需满足:

左括号必须用相同类型的右括号闭合。
左括号必须以正确的顺序闭合。
注意空字符串可被认为是有效字符串。

示例 1:

输入: "()"
输出: true

示例 2:

输入: "()[]{}"
输出: true

 解法1 :

class Solution:
    def isValid(self, s: str) -> bool:
        if not s:
            return True
        qu_dict = {'(': ')', ')':'(', '{':'}', '}': '{', '[':']', ']':'['}
        # 括号匹配, 先进后出, 后入先出
        result = []
        for item in s:
            if item in [')', '}', ']'] and qu_dict[item] in result:
                # 可以进去, 是否消除
                if len(result) > 0 and result[-1] == qu_dict[item]:
                    result.pop()
                else:
                    result.append(item)
            elif item in ['(', '{', '[']:  # 直接进 不消除
                result.append(item)
            else: 
                return False
        if result:
            return False
        return True

解法2: 大神的奇思妙想,  直接替换

class Solution:
    def isValid(self, s: str) -> bool:
        while '()' in s or '[]' in s or '{}' in s:
            s = s.replace('()', '')
            s = s.replace('[]', '')
            s = s.replace('{}', '')
        if s:
            return False
        return True

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

剑指 Offer 48. 最长不含重复字符的子字符串

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

示例 1:

输入: s = "abcabcbb"
输出: 3 
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。

示例 3:

输入: s = "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。
     请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串

解法1: 自创, 思路后续补

class Solution:
    def lengthOfLongestSubstring(self, s: str) -> int:
        max_length = 0
        zichuan = []
        for item in s:
            zichuan.append(item)
            if item in zichuan[:-1]:
                item_index = zichuan.index(item)
                zichuan = zichuan[item_index+1:] # 去掉前面重复的

            max_length = max(max_length, len(zichuan))
        return max_length

解法2: 官方 滑动窗口

class Solution:
    def lengthOfLongestSubstring(self, s: str) -> int:
        # 官方解法 滑动窗口, 找 从头开始, 以每个字符开始 对应的 最长子串(没有重复字符), 比较长度 找到最大的;
        
        s_len = len(s)
        nk, max_len = -1, 0  # nk表示滑动窗口右侧,-1表示还没移动
        sets = set() # 哈希表, 判断是否 重复字符
        for i in range(s_len):
            if i != 0:
                sets.remove(s[i-1])  # 开始指针下移一步
            while nk+1 < s_len and s[nk+1] not in sets:
                sets.add(s[nk+1])
                nk = nk + 1
            # 出现重复的值了, 就是 i~nk 没有重复字符的 最长字串
            max_len = max(max_len, nk-i+1) 
        return max_len

7. 394. 字符串解码

给定一个经过编码的字符串,返回它解码后的字符串。

编码规则为: k[encoded_string],表示其中方括号内部的 encoded_string 正好重复 k 次。注意 k 保证为正整数。

你可以认为输入字符串总是有效的;输入字符串中没有额外的空格,且输入的方括号总是符合格式要求的。

此外,你可以认为原始数据不包含数字,所有的数字只表示重复的次数 k ,例如不会出现像 3a 或 2[4] 的输入。

示例 1:

输入:s = "3[a]2[bc]"
输出:"aaabcbc"

解法1: 

class Solution:
    def decodeString(self, s: str) -> str:
        ### 简单在 所有数字 只表示重复次数k, 数字只表示重复;
        res = []
        for item in s:
            if item == "]": # 遇到"]" 回溯
                ress = ""
                while res and res[-1] != '[': # 方括号内部字母
                    ress = res.pop()+ress
                res.pop() # 输出[
                # 得到方括号前的数字
                nums = ""
                while res and res[-1].isdigit():
                    nums = res.pop()+nums
                if nums:
                    res.append(int(nums) * ress)
                else:
                    res.append(ress)
            else:
                res.append(item)
        # print(res)
        return "".join(res)

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

day 5: 字符串 的相关文章

随机推荐

  • pcl求取三维模型每个点的曲率以及法向量

    转载 xff1a http blog csdn net lming 08 article details 18360329 做个笔记 xff0c 写得很不错
  • 3D人脸重建: BFM结合表情模型

    MATLAB代码 xff1a addpath genpath pwd gt model 载入原始的BFM模型 load 39 raw 01 MorphableModel mat 39 载入3dffa中 BFM信息 load 39 3ddfa
  • 构建副对角线全为1的矩阵,

    突然用到 副对角线 全为1的矩阵 xff0c 不知道怎么调用numpy xff0c 自己写了一个 xff1a import numpy as np 副对角线 全为 1 def get subdiag n value ar 61 for i
  • day1: 357. 计算各个位数不同的数字个数

    给定一个非负整数 n xff0c 计算各位数字都不同的数字 x 的个数 xff0c 其中 0 x lt 10n 示例 输入 2 输出 91 解释 答案应为除去 11 22 33 44 55 66 77 88 99 外 xff0c 在 0 1
  • day1: 二叉树

    1 二叉树的层序遍历 给你一个二叉树 xff0c 请你返回其按 层序遍历 得到的节点值 xff08 即逐层地 xff0c 从左到右访问所有节点 xff09 示例 xff1a 二叉树 xff1a 3 9 20 null null 15 7 3
  • 求正整数的平方根

    34 34 34 求正整数的平方根 二分查找 34 34 34 def sqrt val t if val lt 0 or t lt 0 return 0 left 61 0 right 61 val mid 61 left 43 righ
  • 对BN的理解

    BN原理与使用过程详解 内部协变量偏移 Internal Covariate Shift 和批归一化 Batch Normalization 对于BN层的理解 关于BN防止过拟合的分析 BN Batch Normalization 原理与使
  • 感受野的计算方法

    卷积神经网络基础题 如何计算多层卷积 池化网络每一层的感受野 Receptive Field
  • day2:215. 数组中的第K个最大元素 快速排序 python代码

    34 34 34 快速排序 思想 xff1a 基本思想是 xff1a 通过一趟排序将要排序的数据分割成独立的两部分 xff0c 其中一部分的所有数据都比另外一部分的所有数据都要小 xff0c 然后再按此方法对这两部分数据分别进行快速排序 x
  • 梯度消失和梯度爆炸原因及其解决方案

    梯度消失和梯度爆炸原因及其解决方案
  • day3: 剑指 Offer 48. 最长不含重复字符的子字符串

    剑指 Offer 48 最长不含重复字符的子字符串 请从字符串中找出一个最长的不包含重复字符的子字符串 xff0c 计算该最长子字符串的长度 示例 1 输入 34 abcabcbb 34 输出 3 解释 因为无重复字符的最长子串是 34 a
  • idea中java版本设置

    1 打开file gt Project structure gt project Settings gt Project gt Project SDK中设置 2 设置IDEA本身的jdk版本 打开file gt settings gt ja
  • 剑指 Offer 59 - II. 队列的最大值

    剑指 Offer 59 II 队列的最大值 请定义一个队列并实现函数 max value 得到队列里的最大值 xff0c 要求函数max value push back 和 pop front 的均摊时间复杂度都是O 1 若队列为空 xff
  • 剑指 Offer 46. 把数字翻译成字符串

    剑指 Offer 46 把数字翻译成字符串 给定一个数字 xff0c 我们按照如下规则把它翻译为字符串 xff1a 0 翻译成 a xff0c 1 翻译成 b xff0c xff0c 11 翻译成 l xff0c xff0c 25 翻译成
  • python 异或的应用

    符号 描述 运算规则 amp 与 两个位都为1时 xff0c 结果才为1 xff08 统计奇数 xff09 全1为1 或 两个位都为0时 xff0c 结果才为0 xff08 统计偶数 xff09 全0为0 异或 两个位相同为0 xff0c
  • day4: 剑指 Offer 64. 求1+2+…+n

    剑指 Offer 64 求1 43 2 43 43 n 求 1 43 2 43 43 n xff0c 要求不能使用乘除法 for while if else switch case等关键字及条件判断语句 xff08 A B C xff09
  • day5: 链表

    1 剑指 Offer 22 链表中倒数第k个节点 输入一个链表 xff0c 输出该链表中倒数第k个节点 为了符合大多数人的习惯 xff0c 本题从1开始计数 xff0c 即链表的尾节点是倒数第1个节点 例如 xff0c 一个链表有6个节点
  • LCP 18. 早餐组合

    小扣在秋日市集选择了一家早餐摊位 xff0c 一维整型数组 staple 中记录了每种主食的价格 xff0c 一维整型数组 drinks 中记录了每种饮料的价格 小扣的计划选择一份主食和一款饮料 xff0c 且花费不超过 x 元 请返回小扣
  • 第 208 场周赛

    1 5523 文件夹操作日志搜集器 class Solution def minOperations self logs List str gt int 栈 xff0c 先进 后出 zhan 61 39 main 39 for log in
  • day 5: 字符串

    1 剑指 Offer 38 字符串的排列 输入一个字符串 xff0c 打印出该字符串中字符的所有排列 你可以以任意顺序返回这个字符串数组 xff0c 但里面不能有重复元素 示例 xff1a 输入 xff1a s 61 34 abc 34 输