LeetCode 探索初级算法-字符串:14 字符串中的第一个唯一字符-20200324

14 字符串中的第一个唯一字符-20200324

题目

给定一个字符串,找到它的第一个不重复的字符,并返回它的索引。如果不存在,则返回 -1。

示例

s = "leetcode"
返回 0.

说明

您可以假定该字符串只包含小写字母。


注意事项

  1. 空字符串的情况。

思路一

因为题目要求是小写的英文字母,一共就26个,ASCII码从97到122。所以可以设置一个长度为26的数组,里面存储着对应字母在字符串中的索引,遇过重复了就将值改为-1,最后除-1外找到最小的值。

修改经历:

1. 忘记考虑没有不重复的情况了。(第一次提交)

  • 解答错误。

2. 修改后提交,提交成功。(第二次提交)

  • 执行用时 :152 ms, 在所有 Python3 提交中击败了45.43%的用户
  • 内存消耗 :13.6 MB, 在所有 Python3 提交中击败了6.57%的用户

心得体会:

字符转ASCII码相互转化的知识点放在下面的Python 3 知识点复习中了,第6条。感觉肯定有比着更好的算法。

最终代码展示:

class Solution:
    def firstUniqChar(self, s: str) -> int:
        ca = []  # char array
        for _ in range(0, 26):
            ca.append(-1)
        for i in range(0, len(s)):
            ind = ord(s[i])-97
            if ca[ind] >= 0:
                ca[ind] = -2
            elif ca[ind] == -1:
                ca[ind] = i
            else:
                pass
        if max(ca) < 0:
            return -1
        else:
            mav = max(ca)  # max value
            for j in range(0, 26):
                ca[j] = mav if ca[j] in [-1, -2] else ca[j]
            return min(ca)

思路二

利用 Python 中的 Collections 包中的 Counter 来实现自动统计元素重复次数。把第一个重复次数为1的元素,index输出就行。柑橘有点作弊,哈哈哈。

修改经历:

1.一次成功。(第一次提交)

  • 执行用时 :192 ms, 在所有 Python3 提交中击败了28.46%的用户
  • 内存消耗 :13.7 MB, 在所有 Python3 提交中击败了6.57%的用户

心得体会:

这也不快啊。。。不过真得很简单。

最终代码展示:

from collections import Counter
class Solution:
    def firstUniqChar(self, s: str) -> int:
        count = Counter(s)
        for ind, item in enumerate(s):
            if count[item] == 1:
                return ind
            else:
                pass
        return -1

思路三

这个是从大神那里看到的,因为字母就26个,所以采用 String 的特有方法, find() 和 rfind() ,一个从左向右查,一个从右往左查,两个相等时就是不重复的元素了。比较那个不重复的元素index小,就行了。虽然要遍历26遍,但也是O(N)的复杂度。

修改经历:

1. 一次成功。(第一次提交)

  • 执行用时 :36 ms, 在所有 Python3 提交中击败了98.73%的用户
  • 内存消耗 :13.4 MB, 在所有 Python3 提交中击败了6.81%的用户

心得体会:

自带的算法优化得很好了,find 和 rfind 相当于两个指针了。

最终代码展示:

class Solution(object):
    def firstUniqChar(self, s: str) -> int:
        chStr = "abcdefghijklmnopqrstvuwxyz"
        mInd = len(s)
        for ch in chStr:
            if s.find(ch) != -1 and s.find(ch)==s.rfind(ch):
                mInd = min(mInd, s.find(ch))
        return mInd if mInd != len(s) else -1

思路四

用到了有序字典,这和一般的字典不一样。相比于一般的字典都是任意位置,有序字典会记录插入顺序。这也就是说只要两个字典的元素相同就可以,而有序字典的顺序也必须相同。这个函数在 collections 包中的 OrderedDict() 函数。该函数可以想数组一样操作。

修改经历:

1. 一次成功。(第一次提交)

  • 执行用时 :124 ms, 在所有 Python3 提交中击败了63.75%的用户
  • 内存消耗 :13.6 MB, 在所有 Python3 提交中击败了6.57%的用户

心得体会:

有序字典也慢啊。

最终代码展示:

from collections import OrderedDict
class Solution(object):
    def firstUniqChar(self, s: str) -> int:
        orDic = OrderedDict()
        for ch in s:
            orDic[ch] = orDic[ch] + 1 if ch in orDic else 1
        for k, v in orDic.items():
            if v == 1:
                return s.index(k)
            else:
                pass
        return -1

思路五

题解大神的思路,字典加过滤器(filter)。这里介绍下 filter() 这个 Python 的内置函数。

  • 函数形式:filter(judge function(), iterable)
  • 说明:filter 会将 iterable 中的元素逐一放入 judge function 中判断,并返回一个符合条件的list,这个list和iterable的形式一致。

再介绍下字典的 items() 方法。keyValuePair = dict.items() 返回的一个元组,keyValuePair[0] 是 key,keyValuePair[1] 是 value。

修改经历:

1. 没有考虑到filter返回的list的形式,在这里的filter返回的list依然是字典的形式,所以只需要把key取出来就好。(第一次提交)

  • 解答错误。

2. 提交成功。(第二次提交)

  • 执行用时 :128 ms, 在所有 Python3 提交中击败了60.68%的用户
  • 内存消耗 :13.7 MB, 在所有 Python3 提交中击败了6.57%的用户

心得体会:

学会了filter,开心。

最终代码展示:

from collections import OrderedDict
class Solution(object):
    def firstUniqChar(self, s: str) -> int:
        dic = {}
        for item in s:
            dic[item] = dic[item] + 1 if item in dic else 1
        uniqueChar = [key for key, value in filter(lambda x: x[1] == 1, dic.items())]
        for ind, item in enumerate(s):
            if item in uniqueChar:
                return ind
            else:
                pass
        return -1
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值