找到字符串中第一个不重复的元素
今天面试的时候遇到这个题目,很悲剧,当成找到字符串中第一个“重复”的元素了,用了双重for循环,冒泡排序去写的,回家的路上又想了一种利用Map特性,写了一种比较方便的写法,后来再沟通的时候,才知道自己写错了,少了个「不」字,很悲催,于是回家后又写了个「不重复」元素的查找方法,然后在网上找答案,找到几篇,同样有利用冒泡排序去写的,不过用的是java,总感觉怪怪的,一下是代码:
private fun findFirstStr(text: String): String {
if (text.isEmpty()) return ""
val c = text.toCharArray()
for (i in 0 until c.size) {
val char = c[i]
for (j in i + 1 until c.size - i) {
if (char == c[j])
break
}
return char.toString()
}
return ""
}
这个能找出什么来?
不知道,运行测试
例如原始字符串为"abcdea",输出结果为"a",貌似没错是吧?
输入“a”,结果显示“a”,好像也不可能是别的,
如果输入"aab"呢?结果还是“a”,这就错了吧,
测试后发现除了前两种情况,当一个char在字符串里重复多次,或者多个char重复多次后,这种冒泡排序完全无法找出来正确的结果,一下是自己写的,没用什么高深的算法,只是用了map的唯一Key特性
private fun getFirstString(text: String): String {
if (text.isEmpty()) return ""
val c = text.toCharArray()
// 保存未重复的Char
val map = mutableMapOf<Char, Char>()
// 保存重复的Char
val mapR = mutableMapOf<Char, Char>()
var char: Char
for (i in 0 until c.size) {
char = c[i]
if (map[char] != null) {
mapR[char] = char
} else {
map[char] = char
}
}
for (i in 0 until c.size) {
if (mapR[c[i]] == null)
return c[i].toString()
}
return ""
}
首先来看这个题目,找到第一个不重复的元素,这里就有个坑,在字符串里元素个数、元素重复次数、元素重复位置都不确定,使用冒泡、选择排序,看着是走了两边遍历,可是无法判断是哪个元素重复了,重复了几次,当然可以记录、可以转换成list删除、可是删除的时候,每确定一个元素有重复,就需要遍历整个list去删除存在的相同元素,删除后list的size被修改,又需要计算从哪里开始重新遍历剩余元素,逻辑便更加混乱,要么写多重嵌套,要么写递归,「递归」?
所以这里使用map来处理相同元素的问题,思路是用两个map分别存储出现过重复的数据跟未重复的数据,然后遍历原始字符串转换成的charArray,不处在于「重复map」中的第一个就是原始数据中的第一个不重复字符串了,如果有更好的方法,留言mmm
然后忽然发现,简单的问题复杂化了,新的代码,在eclipce上写的
private static String findFirstDefWord(String text) {
if (text.isEmpty())
return "";
for (int i = 0; i < text.length(); i++) {
String newStr = text.replaceAll(text.charAt(i) + "", "");
int count = text.length() - newStr.length();
if (count == 1)
return text.charAt(i) + "";
}
return "";
}