字符串总结点睛

一、知识点总结

1、char ——> string

// 定义一个大小为1,值为 i+'a' 的字符串
string s(1, i + 'a');

2、定义数组

定义一个大小为26的数组,并将其初始化为 0

int arr[26] = {0};

3、数组填充问题

很多数组填充类的问题,都可以先预先给数组扩容带填充后的大小,然后在从后向前进行操作。
利用双指针,从后往前进行填充

这么做有两个好处:

  • 不用申请新数组。
  • 从后向前填充元素,避免了从前先后填充元素要来的 每次添加元素都要将添加元素之后的所有元素向后移动

4、字符串和数组的差别

字符串是若干字符组成的有限序列,也可以理解为是一个字符数组,但是很多语言对字符串做了特殊的规定,接下来我来说一说C/C++中的字符串。

在C语言中,把一个字符串存入一个数组时,也把结束符 '\0’存入数组,并以此作为该字符串是否结束的标志。

在C++中,提供一个string类,string类会提供 size接口,可以用来判断string类字符串是否结束,就不用’\0’来判断是否结束。

那么vector< char > 和 string 又有什么区别呢?

其实在基本操作上没有区别,但是 string提供更多的字符串处理的相关接口,例如string 重载了+,而vector却没有。

所以想处理字符串,我们还是会定义一个string类型

5、最长回文串

解法一:KMP

解法二:马拉车 Manacher

解法三:动态规划

解法四:哈希

二、做题总结

第3题 最长不含重复字符

本题与 剑指offer48 相同

第14题 最长公共前缀

第205题 同构字符串

建立 s 与 t 的两个映射,从 s 到 t,或者是从 t 到 s ,

两个映射都要满足,财富和是同构关系,否则就是属于异构关系

第290题 单词规律

本题与 205 相似,都是两个映射关系。只不过这个题,一个是 <char, string>,一个是<string, char>

说是 easy 题,其实还是有点难啊~ 没见过这个套路的话,会很难想的到

1、关于两个字符串的处理

patten 串是一个一个字符来看

s 串是要自己做分割的,以空格为分界

2、关于映射关系

本题要建立两个映射关系,用哈希映射来对 pattern 和 s 建立一一对应的关系

ch2str

str2ch

这两个映射都满足才是符合题意,否则就return false

第1002题 查找常用字符

对 vector& word 这个原始字符串数组的处理,分为 第一个字符串 和 剩余字符串

这里因为是对单个字符的处理,因此可以用 大小为26的数组来代替

第一个字符串先映射到哈系数组int word[26] = {0}中

然后遍历剩下的字符串,每次遍历剩余字符串中的某个时,也需要建立一个临时的 哈系数组int temp[26] = {0}用来存储映射关系

对这个临时哈系数组映射之后,需要将其余第一个字符串的哈希数组进行比较,更新word是每个下标的都保证是最小值

最后遍历 word,取出对应的元素即可,注意这里是可以有重复元素,而且重复的元素也需要重复的输出

第49题 字母异位分组

本题感觉在联系 哈希映射的嵌套关系

对内层的处理还是很不容易想到的,使用到了 emplace_back()

  • 哈希

  • 用数组代替哈希

    • int arr[26] = {0}; // 初始化一个大小为26,初值为0的数组
  • char ——> string

// 定义一个大小为1,值为 i+'a' 的字符串
string s(1, i + 'a');

第249题 移位字符串分组

本题和49题·有点相似,都需要两层的映射关系

49题的处理,是把第一层的映射相当于按字典进行排序,将排序后得到的字符串作为第二次映射的 key

249题的处理,是把第一层的映射都映射为与a有相对距离的关系,然后将这个映射的结果作为 key

感觉这两题还是挺不容易想到的,有点难哦~

本题的两个映射过程

  • 1、第一个映射:将原始的字符串 prestr 映射为以a开头的字符串 str,注意str的顺序已经发生了异位
    ch = (ch - prestr[0] + 26) % 26 + 'a';
  • 2、第二个映射:哈希映射,将映射后的字符串 str 作为哈希的 key,原始的字符串 prestr 作为 value,组成对
    mp[str].push_back(prestr);

第151题 花式反转字符串

这个题好难呀!

给定一个字符串,逐个翻转字符串中的每个单词。
输入字符串可以在前面或者后面包含多余的空格,但是反转后的字符不能包括。
如果两个单词间有多余的空格,将反转后单词间的空格减少到只含一个。

输入: “the sky is blue”
输出: “blue is sky the”

输入: “a good example”
输出: “example good a”

解题的思路:

整体反转+局部反转 的思想

  • 移除多余空格(用双指针法。注意字符串的 前 中 尾 要分三种情况来处理)
  • 将整个字符串反转
  • 把每个单词反转

剑指58-2题

再来一道绝妙的题——左旋字符串

1、反转区间为前n的子串
2、反转区间为n到末尾的子串
3、反转整个子串

经历了上一题的苦难这道题就轻松多了hhhhh

第692题 前K个高频单词

1、看到 前K大 这三个字,应该有 DNA 反应,可以用 堆排序,或者快速排序

2、关于怎么使用堆排序?

  • 使用 lambda 表达式 + decltype
    • decltype 被称作类型说明符,decltype的结果不是值,而是一个类型。它的作用是选择并返回操作数的数据类型,它的出现主要是解决复杂的类型声明。
  • 使用 struct + 重载操作符()

这两种方式在细节处理上有所偏差,但是逻辑上类似,都是将哈希表中的元素全部取出来,建立一个大小为 K 的堆,里面不断排序,最后得到的就是前K大的单词了

3、怎么使用快速排序

  • 逻辑:用一个数组将哈希表装起来,然后再里面找到第K大的数,然后根据快速排序的逻辑,保证下标为 [0, k-1] 上的数是前K大的数,但是这个排序的过程不能保证这K个数的顺序,因此需要再这K个数上再进行一次排序,最后输出即可。

解题思路

两步走

  • 第一步:使用哈希表,统计相同字符串
  • 第二步:在哈希表中,选出频次前K大的单词

时间复杂度分析

  • 假设总共有n个单词,哈希表中单词数为m个,选出前k个高频单词,因此有 n ≥ m ≥ k
  • 哈希映射 O(n)
  • 堆排序 O(m logk)
  • 快排分了两步,首先选出第K个大的元素O(m),然后对前k个数排序需要 O(k logk),所以总共是 O(m + klogk)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值