查找第一个不重复的字符问题
查找第一个不重复的字符问题
最近去面了一次试,最后面到一次算法题。说实话,以前去面试很少面到算法题,可能和面试的职位有关的。
相当常见的题目,说是找出一堆数字中第一个出现的不重复的数字。当时没理解清题目,想成了是只有一个不重复的数字。后来面试官跟我说明清楚了题目之后,瞬间没了啥思路,也没答好。后来回去路上一想,感觉也相当简单。
这个题目原题是 “找出一个字符串(只包含英文,不考虑中文等字符问题)中第一个不重复的数字”。
如果不做限制,很容易想到的方法是:从头开始遍历一下字符串,针对每个字符再从开开始查找是否有重复的,找到第一个整个字符串中没有重复的字符。当然时间复杂度为 O(n2),肯定不是最优解。
比较普遍的方法是牺牲一定的空间复杂度,用一个数组暂存一下字符串中每个字符出现的次数,再重新从头开始遍历字符串,找到次数为 1 的字符返回。
代码如下:
func searchFirstNotDuplicatedChar(str string) string {
cnts := make([]int, 256)
for _, s := range str {
cnts[s]++
}
for _, s := range str {
if cnts[s] == 1 {
return string(s)
}
}
return ""
}
复杂度就是遍历了两次字符串,时间复杂度为 O(n)。已经相当可以了。
当然面试官给我出的原题是一堆数字,不是字符串(这和我面试时提到的以往的工作有关,处理批量数据)。因为我们知道英文字符处于 ASCII 码表中很容易做对应。而数字类数据的话因为不知道范围,很难用一个数组来做存储对应,所以这个我们可以考虑用一个 Map。我们知道 Hash 方法是很快速的,所以几乎不存在什么性能问题。
这个为了简便,只考虑了整形 int 类型的数据。
func findFirstNotDuplicatedInt(nums []int) int {
cnts := make(map[int]int)
for _, num := range nums {
cnts[num]++
}
for _, num := range nums {
if cnts[num] == 1 {
return num
}
}
return -1
}
就稍微改了一下,依然是 O(n)。差不多是这个。据说还有使用位运算的算法可以做到,暂时没研究,感觉这样已经很不错了。
对于算法题,面试和自己平常在电脑上做,感觉真是不一样的。面试中包含各种不确定的因素,而且人也容易产生紧张感,往往有些平常很容易想到的东西面试中就犯迷糊了。复杂的算法由于平时几乎不太用到,也是看过就很容易忘。所以我觉得培养一种对于算法的直觉相当重要。
posted on 2018-07-23 00:52 alfred_zhong 阅读(2277) 评论(0) 编辑 收藏 举报