一、词语变形
题型:
给定两个字符串str1和str2,如果str1和str2中出现的字符种类一样且每种字符出现的次数也一样,那么str1与str2互为变形词,请实现函数判断两个字符是否互为变形词
举例:
str1=“123”,str2=“231”,返回true;
str1=“123”,str2=“2331”,返回false;
思路:
使用哈希表实现对字符的计数,首先对str1创建哈希表1,记录字符出现的种类和每种字符出现的次数;然后对str2创建哈希表2;最后对比哈希表1和哈希表2的记录是否一致。(同时可以使用固定长度的数组替代哈希表的结构,这样更加节省空间,速度也更快)
例题:
对于两个字符串A和B,如果A和B中出现的字符种类相同且每种字符出现的次数相同,则A和B互为变形词,请设计一个高效算法,检查两给定串是否互为变形词。
给定两个字符串A和B及他们的长度,请返回一个bool值,代表他们是否互为变形词。
代码举例:
import java.util.*;
public class Transform {
public boolean chkTransform(String A, int lena, String B, int lenb) {
// write code here
//首先,如果两个字符串的长度不同,那么意味着这都两个字符串要么存在不同的元素,要么元素数量不同。
if(A==null || B==null || lena!=lenb){
return false;
}
//首先将这来两个字符串转换为字符数组
char[] chaA = A.toCharArray();
char[] chaB = B.toCharArray();
//然后创建一个固定数组来表示哈希表结构,这里如果ascll码范围为65535的话就创建一个长度为65536的数组
//这里ascll码长度为255,这里map的下标其实就是表示字符的ascll码的数值
int[] map = new int[256];
//遍历第一个字符数组,创建哈希表结构
for(int i=0;i<chaA.length;i++){
map[chaA[i]]++;
}
//接下来遍历第二个字符数组
for(int j=0;j<chaB.length;j++){
//如果没有,则表示存在不同的字符,或者经过减一操作,A中的相同字符已经减为0
if(map[chaB[j]]==0){
return false;
}
//没判断一次,将哈希表记录数减一
map[chaB[j]]--;
}
return true;
}
}
二、旋转词判断
例题:
给定两个字符串,str1和str2,把str前面任意的部分挪到后面形成的字符串叫做str的旋转词。比如str=“1234”,那么str的旋转词有“1234”,“2341”,“3412”,“4123”。给定两个字符串a和b,请判断a和b是否互为旋转词。
思路:
首先解决这个题目的最佳时间复杂度为O(n),然后我们首先要判断这两个字符串长度是不是相等的,首先生成一个str1+str1的大字符串,然后用KMP算法判断大字符串中是否包括str2,如果包括则str2和str1互为旋转词。
import java.util.*;
public class Rotation {
public boolean chkRotation(String A, int lena, String B, int lenb) {
// write code here
//首先判断字符串是否相等
if(lena != lenb){
return false;
}
//创建大字符串
String big = A+A;
return getIndexOf(big,B) != -1;
}
//调用KMP算法,计算最大子串
public int getIndexOf(String s, String m) {
if (s == null || m == null || m.length() < 1 || s.length() < m.length()) {
return -1;
}
char[] ss = s.toCharArray();
char[] ms = m.toCharArray();
int[] nextArr = getNextArray(ms);
int index = 0;
int mi = 0;
while (index < ss.length && mi < ms.length) {
if (ss[index] == ms[mi]) {
index++;
mi++;
} else if (nextArr[mi] == -1) {
index++;
} else {
mi = nextArr[mi];
}
}
return mi == ms.length ? index - mi : -1;
}
//获取next数组
public int[] getNextArray(char[] ms) {
if (ms.length == 1) {
return new int[] { -1 };
}
int[] nextArr = new int[ms.length];
nextArr[0] = -1;
nextArr[1] = 0;
int pos = 2;
int cn = 0;
while (pos < nextArr.length) {
if (ms[pos - 1] == ms[cn]) {
nextArr[pos++] = ++cn;
} else if (cn > 0) {
cn = nextArr[cn];
} else {
nextArr[pos++] = 0;
}
}
return nextArr;
}
}
当然,如果只是判断str2是否在str1中,我么你只需要调用Java中的一个方法,contains,这个方法可以判断一个字符串是否包含另一个字符串。
代码如下:
import java.util.*;
public class Rotation {
public boolean chkRotation(String A, int lena, String B, int lenb) {
// write code here
if(lena!=lenb){
return false;
}
String C = A+A;
return C.contains(B);
}
}