1.需要掌握的相关概念
1.回文
2.字串(连续)
3.子序列(不连续)
4.前缀树(Trie树)
5.后缀树和后缀数组
6.匹配
7.字典序
1.判断一个二叉树是否另一个二叉树的子树
方法:将二叉树序列化,再使用KMP算法进行匹配即可,时间复杂度O(M+N).
要点:1.将二叉树进行序列化的时需标记出空节点。
2.判断两个词是否互为变形词
变形词:所有字符串出现的次数相同,包括次数为0的
方法:使用Hash表计数后进行比较,其中如果是c/c++语言,可用256长度的数组,java则可用65536长度的数组作为哈希表提高效率。
3.旋转词
1.str1="1234",str2="2341"
2.判断str2是否为str1的旋转词:
1.str=str1+str1 ,即"12341234"
2.利用kmp算法(O(m+n))判断是否str包含str2
3.str中的任意长度为N的子串都是str1的旋转词。
4.字符串倒序
str1="god i like you." 变为str2="you like i god"
步骤:
1.反转字符串为".uoy ekil i dog"
2.逐词反转,"you. like i god"
3.反转方法:
按照字符串长度的奇偶性反转。
5.移动子串
问题描述:给定字符串str,整数i,将0...i移动到N-1-i,N-1,将i+1..N-1移动到0...N-i
如"HELLOWORLD",i=4 DLROWOLLEH
步骤:1.分别局部反转0...i,i+1...N-1 -->"OLLEHDLROW"
2.将整体反转 -->"WORLDHELLO"
(也可以先整体,再局部)
时间复杂度O(N) ,空间复杂度O(1)
6.拼接出字典顺序最小的大字符串
问题描述:给定一个字符串数组,找出一种拼接顺序,使得到的大字符串是所有可能结果中字典顺序最小的
分析:1.这是一个排序问题,需要对该字符串数组进行排序,然后按顺序拼接即可。
2.不能直接对字符串数组中的字符串按字典顺序排序,如[“b","ba"],拼接出的bba比bab实际上大。
方法:重写排序规则,如果str1+str2<str2+str1,则str1<str2.
7.替换空字符为某字符串
问题描述:如将"good for you"替换为"good%20for%20you"。
方法:1.遍历寻找空字符个数,计算出新字符串的长度
2.从后往前置入新字符:如果是空字符,则依次放入'0','2','%',否则置入str[i].直到i=0
8.判断字符串中的括号是否闭合
方法类似于使用栈的方法,只是用一个整数num替换。
方法:遍历字符串,遇到左则num++,右则num--,一旦num<0,返回false
如果遍历结束,num=0,返回true,否则false.
9.求最长无重复子串的长度
分析:
补充:有两种情况,第一种由于上次出现c的位置在pre右边,则c到c'必不重复,由于前一个字符最左不重复位置为pre+1
第二种由于pre出现在c右边,则pre到c必不重复。
这种方法属于动态规划的一种,做到了时间复杂度O(N),空间复杂度取决于Map。
public int longestSubstring(String A, int n) { // write code here if(A==null||n==0) return 0; char[] arr=A.toCharArray(); int[] map=new int[256]; for(int i=0;i<256;i++) map[i]=-1; int pre=-1; int len=0; for(int i=0;i<arr.length;i++){
//pre维护着无重复字串的最左的左一个位置(到i-1位置的无重复字串) pre=Math.max(pre,map[arr[i]]); len=Math.max(len,i-pre); map[arr[i]]=i; } return len; }