刷穿剑指offer-Day08-字符串I 字符串知识总结与题型讲解

前文回顾

上一章我们学习了数组相关的知识与解题,并针对例题讲解了双指针和前缀和的解题思想。其中重点针对双指针的特殊场景滑动窗口进行了细致讨论和解题模板梳理。到这里一些初入刷题不久的朋友也许要想,那是不双指针就只能用来刷数组的题目,其他的就不适用了呢?完全不是...

针对某一类数据结构的算法题目,很多时候解题思维是通用的,不仅是数组会用到双指针,链表、字符串等等同样适用。而且我们在解某一种题目时,经常会通过将该结构转化为其他数据结构的方式来完成解题,而这种场景出现最多的就是字符串类型了。

字符串题目解析

字符串普遍认为它是不可变的,所以如果单纯考察字符串,能涉及到的知识点未免太过狭隘了,难道面试的时候算法题目考些诸如:字符串切片求子串、两个字符串判断是否相等、字符串倒序输出?醒醒,别做梦了,但凡喝酒配点花生米,也不至于醉成这样啊....

力扣上的字符串题目有536道,但这个分类是有问题的,它将所有入参为字符串的题目都分到的这个类型里面,但其实几乎所有字符串的题目都是通过以下几类来完成的,让我们来仔细划分下:

数组

由于字符串是有字符组成的,而算法题中的字符串一般都只会包含26个英文字母,更为简单的一般会告诉你仅包含大/小写字母,那么在判断字符串中包含的英文字母数量时,可以使用一个长度为26的数组根据下标0-25的value值 对应 a-z个字符在字符串中出现的次数。

通过这种方式可以解决很大一部分字符串的题目。

针对括号匹配、路径拆分等字符串题目,使用栈的方式简直手到擒来闭眼AC。当然这里要说明下在Python中,是没有Stack这个数据类型的,它是通过list的append和pop实现栈的压入弹出。

哈希表

哈希表在字符串中也是有一定地位的,我们在解题时可以使用哈希表快速完成一些匹配的关系,比如罗马数字转整数中的循环比较:

tmp = { "I": 1,
        "V": 5,
        "X": 10,
        "L": 50,
        "C": 100,
        "D": 500,
        "M": 1000}

亦或者是判断字符串同构等的题目,也可以通过哈希表的方式轻松解题,这里举例两道简单题目用来了解这种解题方式。

有兴趣的朋友可以先提前去看看:

  • 205.同构字符串
  • 290.单词规律

队列

队列由于其先进先出的特点,可以在循环匹配中帮助我们通过枚举的方式完成部分字符串的题目,比如 17. 电话号码的字母组合

其他类型的还有很多,这里就不逐一介绍了,通过这些例子只是想告诉大家,数据结构是互通的,我们可以通过数据结构的转换来完成解题。并且算法和数据结构不是强绑定的,一个算法在不同的数据结构中经常是通用的。

字符串方法

上面看到由于我们需要将字符串转化为其他的数据类型,那么不可避免的需要用到一些方法。在这里快速介绍下吧。

  1. 获取字符串长度

    • Java: someString.length()
    • Python: len(some_string)
  2. 判断字符串是否相等

    • Java: someString.equals(otherString)
    • Python: some_string == other_string
  3. 获取字符串的子串

    • Java:someString.substring(begin,end)
    • Python: some_string [begin: end:step]
  4. 拆分字符串

    • Java:String[] arr = someString.split(regex);
    • Python: some_string.split(regex,maxsplit)
  5. 获取下标

    • Java: indexOf() lastIndexOf()
    • Python: python 只有index()
  6. 大小写转换

    • Java: toLowerCase() toUpperCase()
    • Python: lower() upper()
  7. Java返回指定下标的字符时,需要使用charAt(),Python无需如此。

对于字符串的题目,理解上面这些就差不多了,接下来,让我们拿一道题目试试手吧。

剑指OfferII014.字符串中的变位词

https://leetcode-cn.com/problems/MPnaiL/solution/shua-chuan-jian-zhi-offer-day08-zi-fu-ch-pasw/

难度:中等

题目

给定两个字符串 s1 和 s2,写一个函数来判断 s2 是否包含 s1 的某个变位词。

换句话说,第一个字符串的排列之一是第二个字符串的 子串 。

提示:

  • 1 <= s1.length, s2.length <= 10^4
  • s1 和 s2 仅包含小写字母

示例

示例 1:
输入: s1 = "ab" s2 = "eidbaooo"
输出: True
解释: s2 包含 s1 的排列之一 ("ba").

示例 2:
输入: s1= "ab" s2 = "eidboaoo"
输出: False

分析

正如上面说到的,双指针的解题思维不仅适用于数组,在字符串中也是适用的。
这道题相信在做过了前面第八、第九题后,可以一眼看出是一道双指针题目。
只不过从int[]的数组转化为了字符串而已。既然数组的双指针我们会做,那么我们只需要将字符串转换为数组即可。
由于本题仅包含小写字母,所以我们维护一个长度为26的数组,使用数组index对应的value值对应a-z字符出现的次数。
那么,为了便于理解我们维护两个数组,arr1、arr2分别表示s1、s2的转换。
然后通过循环逐次判断arr1是否等于arr2,当相等时,表示结果成立return True
如果整体循环结束后,仍未出现相等的场景,则判断结果为False,具体代码如下。

解题

Python:

class Solution:
    def checkInclusion(self, s1: str, s2: str) -> bool:
        arr1, arr2, lg = [0] * 26, [0] * 26, len(s1)
        if lg > len(s2):
            return False

        for i in range(lg):
            arr1[ord(s1[i]) - ord('a')] += 1
            arr2[ord(s2[i]) - ord('a')] += 1

        for j in range(lg, len(s2)):
            if arr1 == arr2:
                return True
            arr2[ord(s2[j - lg]) - ord('a')] -= 1
            arr2[ord(s2[j]) - ord('a')] += 1
        return arr1 == arr2

Java:

class Solution {
    public boolean checkInclusion(String s1, String s2) {
        int[] arr1 = new int[26];
        int[] arr2 = new int[26];
        if (s1.length() > s2.length()){
            return false;
        }
        for (int i = 0; i < s1.length(); i++) {
            arr1[s1.charAt(i) - 'a']++;
            arr2[s2.charAt(i) - 'a']++;
        }
        for (int i = s1.length(); i < s2.length(); i++) {
            if (Arrays.equals(arr1, arr2)) {
                return true;
            }
            arr2[s2.charAt(i - s1.length()) - 'a']--;
            arr2[s2.charAt(i) - 'a']++;
        }
        return Arrays.equals(arr1, arr2);
    }
}

留作业了

在做完了14题后,我们下来可以自己尝试着解决一下同类型的15题,如果这道题掌握了,那么只需要小幅度修改代码即可通过15题。

好了,今天的字符串章节开篇知识就到这里,大家一定要下来记得联系。不管编程还是算法学习,都是一行行敲出来的,看过不等于学会!

欢迎关注我的公众号: 清风Python,带你每日学习Python算法刷题的同时,了解更多python小知识。

我的个人博客:https://qingfengpython.cn

力扣解题合集:https://github.com/BreezePython/AlgorithmMarkdown

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,837评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,551评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,417评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,448评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,524评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,554评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,569评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,316评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,766评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,077评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,240评论 1 343
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,912评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,560评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,176评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,425评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,114评论 2 366
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,114评论 2 352

推荐阅读更多精彩内容