【面试算法】——字符串(三)

一、词语变形

题型:

给定两个字符串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互为变形词,请设计一个高效算法,检查两给定串是否互为变形词。

给定两个字符串AB及他们的长度,请返回一个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);
    }
}

猜你喜欢

转载自blog.csdn.net/qq_36125072/article/details/81668693