zoukankan      html  css  js  c++  java
  • 查找第一个不重复的字符问题

    查找第一个不重复的字符问题

    最近去面了一次试,最后面到一次算法题。说实话,以前去面试很少面到算法题,可能和面试的职位有关的。

    相当常见的题目,说是找出一堆数字中第一个出现的不重复的数字。当时没理解清题目,想成了是只有一个不重复的数字。后来面试官跟我说明清楚了题目之后,瞬间没了啥思路,也没答好。后来回去路上一想,感觉也相当简单。

    这个题目原题是 “找出一个字符串(只包含英文,不考虑中文等字符问题)中第一个不重复的数字”。

    如果不做限制,很容易想到的方法是:从头开始遍历一下字符串,针对每个字符再从开开始查找是否有重复的,找到第一个整个字符串中没有重复的字符。当然时间复杂度为 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)。差不多是这个。据说还有使用位运算的算法可以做到,暂时没研究,感觉这样已经很不错了。

    对于算法题,面试和自己平常在电脑上做,感觉真是不一样的。面试中包含各种不确定的因素,而且人也容易产生紧张感,往往有些平常很容易想到的东西面试中就犯迷糊了。复杂的算法由于平时几乎不太用到,也是看过就很容易忘。所以我觉得培养一种对于算法的直觉相当重要。

  • 相关阅读:
    C#中常见的系统内置委托用法详解(抄录)
    ClassifyHandler 分类处理结构
    AutoFac Ioc依赖注入容器
    深入理解DIP、IoC、DI以及IoC容器
    ASP.NET MVC的请求处理流程
    电商秒杀功能实现
    MVC之Global.asax解析
    MVC基类控制器的会话丢失重新登录权限过滤
    MVC的Action上下文:ActionExecutingContext
    ASP.NET与MVC架构区别总结
  • 原文地址:https://www.cnblogs.com/snowInPluto/p/9352315.html
Copyright © 2011-2022 走看看