IT企业面试题(java描述)-字符串包含(2)-查找字典里面的兄弟字符串

题目:

查找字典里面的兄弟字符串

兄弟字符串概念:长度相同、字符完全相同、顺序不一定一样的字符串,例如“abc”和“cba”就是兄弟字符串,“aab”和“aba”也是

在这里的字典我们为了方便,选用简单的字符串数组来替代,一般大的字典都是大数据的字符串文件


1.思路

(1)暴力轮询

通过双重for循环来轮询两个字符串的每一个字符,相同的变成某个数字,然后再轮询一遍其中一个,如果有不同的字符,则不是兄弟字符串

此方法的时间复杂度是O(m*n+n)

(2)排序法

由于两字符串长度相同、字符完全相同,只是顺序不一样,那么我们先排序,我使用的是快速排序法,然后同时对比两个字符串在同一个位置上取出来的字符,如果相同,则true,不同,则false

此方法的时间复杂度平均是O(mlog(m)+nlog(n)+n)

(3)HashMap方法

在此利用HashMap的key的唯一性

我们把字符当成key放到HashMap去,然后再记录每一个字符的出现次数,最后通过对比map的长度、字符出现的次数来判定是否兄弟字符串

此方法的时间复杂度平均是O(m+n+n)


从时间复杂度来说,无疑是选择后面两种方法,但是后面两种方法直接也存在差异,主要表现在查询字符长度的大小,当字符的长度大于三的时候,第三种方法最快。


2.代码

(1)暴力轮询

package com.ray.interview.ch01.topic_1_2;

/**
 * 搜查字典里面的兄弟字符串
 * 
 * 兄弟字符串概念:长度相同、字符完全相同、顺序不一定一样的字符串,例如“abc”和“cba”就是兄弟字符串,“aab”和“aba”也是
 * 
 * 在这里的字典我们为了方便,选用简单的字符串数组来替代,一般大的字典都是大数据的字符串文件
 * 
 * 
 * @author raylee
 * @date 2016-02-17
 * @version 1.0
 */
public class ContainString_3 {

	public static boolean isBrother(String strSourceA, String strSourceB) {
		boolean isBrother = true;
		if (strSourceA.length() != strSourceB.length()) {
			isBrother = false;
		} else {
			char[] charA_array = strSourceA.toCharArray();
			char[] charB_array = strSourceB.toCharArray();
			// 暴力轮询
			for (int i = 0; i < charA_array.length; i++) {
				for (int j = 0; j < charB_array.length; j++) {
					if (charA_array[i] == charB_array[j]) {
						charA_array[i] = charB_array[j] = 0;
						break;
					}
				}
			}
			for (int i = 0; i < charB_array.length; i++) {
				if (charB_array[i] != 0) {
					isBrother = false;
					break;
				}
			}
		}
		return isBrother;
	}

	public static void main(String[] args) {
		String[] source = { "abc", "cba", "abdc", "tec", "aab", "bbc", "bca" };
		String target = "abc";
		for (int i = 0; i < source.length; i++) {
			if (isBrother(source[i], target)) {
				System.out.println(source[i]);
			}
		}
	}

}

测试输出:

abc
cba
bca


(2)排序法

package com.ray.interview.ch01.topic_1_2;

/**
 * 搜查字典里面的兄弟字符串
 * 
 * 兄弟字符串概念:长度相同、字符完全相同、顺序不一定一样的字符串,例如“abc”和“cba”就是兄弟字符串,“aab”和“aba”也是
 * 
 * 在这里的字典我们为了方便,选用简单的字符串数组来替代,一般大的字典都是大数据的字符串文件
 * 
 * 
 * @author raylee
 * @date 2016-02-17
 * @version 1.0
 */
public class ContainString_4 {

	public static boolean isBrother(String strSourceA, String strSourceB) {
		boolean isBrother = true;
		if (strSourceA.length() != strSourceB.length()) {
			isBrother = false;
		} else {
			char[] charA_array = strSourceA.toCharArray();
			char[] charB_array = strSourceB.toCharArray();
			// 1.排序
			quickSort(charA_array, 0, charA_array.length - 1);
			quickSort(charB_array, 0, charB_array.length - 1);
			// 2.遍历两个char数组,对比每一个字符,其实就是String里面的equals,但是我们这里不准备使用库函数
			int i = 0;
			int n = charA_array.length;
			while (n-- != 0) {
				if (charA_array[i] != charB_array[i]) {
					isBrother = false;
					break;
				}
				i++;
			}
		}
		return isBrother;
	}

	/**
	 * 快速排序
	 * 
	 * @param chars
	 * @param start
	 * @param end
	 */
	public static void quickSort(char[] chars, int start, int end) {
		if (start < end) {
			char base = chars[start]; // 选定的基准值(第一个数值作为基准值)
			char temp; // 记录临时中间值
			int i = start, j = end;
			do {
				while ((chars[i] < base) && (i < end))
					i++;
				while ((chars[j] > base) && (j > start))
					j--;
				if (i <= j) {
					temp = chars[i];
					chars[i] = chars[j];
					chars[j] = temp;
					i++;
					j--;
				}
			} while (i <= j);
			if (start < j)
				quickSort(chars, start, j);
			if (end > i)
				quickSort(chars, i, end);
		}
	}

	public static void main(String[] args) {
		String[] source = { "abc", "cba", "abdc", "tec", "aab", "bbc", "bca" };
		String target = "abc";
		for (int i = 0; i < source.length; i++) {
			if (isBrother(source[i], target)) {
				System.out.println(source[i]);
			}
		}
	}

}

测试输出:

abc
cba
bca


(3)HashMap方法

package com.ray.interview.ch01.topic_1_2;

import java.util.HashMap;
import java.util.Iterator;

/**
 * 搜查字典里面的兄弟字符串
 * 
 * 兄弟字符串概念:长度相同、字符完全相同、顺序不一定一样的字符串,例如“abc”和“cba”就是兄弟字符串,“aab”和“aba”也是
 * 
 * 在这里的字典我们为了方便,选用简单的字符串数组来替代,一般大的字典都是大数据的字符串文件
 * 
 * 
 * @author raylee
 * @date 2016-02-17
 * @version 1.0
 */
public class ContainString_5 {

	public static boolean isBrother(String strSourceA, String strSourceB) {
		boolean isBrother = true;
		if (strSourceA.length() != strSourceB.length()) {
			isBrother = false;
		} else {
			char[] charA_array = strSourceA.toCharArray();
			char[] charB_array = strSourceB.toCharArray();

			// 1.把字符放到散列表里面
			HashMap mapA = new HashMap<>();
			for (int i = 0; i < charA_array.length; i++) {
				if (mapA.get(charA_array[i]) == null) {
					mapA.put(charA_array[i], 1);
				} else {
					mapA.put(charA_array[i], mapA.get(charA_array[i]) + 1);
				}
			}

			HashMap mapB = new HashMap<>();
			for (int i = 0; i < charB_array.length; i++) {
				if (mapB.get(charB_array[i]) == null) {
					mapB.put(charB_array[i], 1);
				} else {
					mapB.put(charB_array[i], mapB.get(charB_array[i]) + 1);
				}
			}

			// 2.对比散列表
			if (mapA.size() != mapB.size()) {// 由于字符相同,因此map的size相同,不同则不是
				isBrother = false;
			} else {
				Iterator keyIterator = mapA.keySet().iterator();
				while (keyIterator.hasNext()) {
					Character key = (Character) keyIterator.next();
					if (mapA.get(key) != mapB.get(key)) {
						isBrother = false;
						break;
					}
				}
			}
		}
		return isBrother;
	}

	public static void main(String[] args) {
		String[] source = { "abc", "cba", "abdc", "tec", "aab", "bbc", "bca" };
		String target = "abc";
		for (int i = 0; i < source.length; i++) {
			if (isBrother(source[i], target)) {
				System.out.println(source[i]);
			}
		}

	}

}

测试输出:

abc
cba
bca


总结:这一章节主要介绍查找字典里面的兄弟字符串的几种方法。


你可能感兴趣的:(面试题)