LeetCode初级算法之字符串:有效字母异位和字符串第一个唯一字符

今天,写两个字符串的题目,因为这一块刚开始的题目比较简单,思路也不是太多,所以两个写到一篇博客。

字符串中的第一个唯一字符

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

案例:
s = “leetcode”
返回 0.
s = “loveleetcode”,
返回 2.

注意事项:您可以假定该字符串只包含小写字母。
这个题思路比较单一, 遍历一遍数组,并统计每个字符的个数,我用的unordered_map,因为碰到字符计数的,第一感觉就想到了map, 然后遍历一遍unordered_map,看第一个值为1的就是答案。返回坐标。

class Solution {
public:
    int firstUniqChar(string s) {

        int len = s.size();
        int res = -1;

        unordered_map <int, int> m;

        for (int i=0; i<len; i++)
        {
            m[s[i]]++;

        }

        for (int i=0; i<len; i++)
        {
            if (m[s[i]] == 1)
            {
                res = i;
                break;
            }
        }

        return res;
    }
};

这个题思路比较单一。 最好别用暴力,第一次用暴力超时了。

有效的字母异位词

给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的字母异位词。

示例 1:
输入: s = “anagram”, t = “nagaram”
输出: true
示例 2:
输入: s = “rat”, t = “car”
输出: false
说明:
你可以假设字符串只包含小写字母。

进阶:
如果输入字符串包含 unicode 字符怎么办?你能否调整你的解法来应对这种情况?

1. 思路一 - 基于排序

这个是我的初始思路,就是给两个字符串排序,如果是字母异位词,两个字符串应该相等,否则,就不是,所以这个用C++实现,代码挺短的。

class Solution {
public:
    bool isAnagram(string s, string t) {

        if (s.size() != t.size())
            return false;

        sort(s.begin(), s.end());
        sort(t.begin(), t.end());

        if (s!=t)
            return false;

        return true;

    }
};

这个思路比较清晰,但是时间复杂度有点高,涉及到了两次排序,时间复杂度O(nlogn)。

思路二 - 基于map

第一个思路的时间复杂度有点高,所以就又想起了计数的思想, 可以再用map,遍历第一个字符串,用map自增计数,然后遍历第二个字符串,用map自减计数。如果两个是异位字符串,那么最后map 的值应该是0,否则,不是。

class Solution {
public:
    bool isAnagram(string s, string t) {

        map <char, int> m;
        int lens = s.size();
        int lent = t.size();

        if (lens != lent)
            return false;

        for (int i =0; i<lens; i++)
        {
            m[s[i]]++;
        }

        for (int i=0; i<lent; i++)
        {
            m[t[i]]--;
        }

        map <char, int>::iterator it;
        for (it=m.begin(); it!=m.end(); it++)
        {
            if (it->second != 0)
                return false;
        }
        return true;
    }
};

这个效率要比上面的思路一高一些。

思路三 - 基于数组统计个数

由于这个题里面只说了可以假设都是小写字母,那么只需要统计26个小写字母的个数即可,所以,用一个数组统计会快很多,因为直接基于下标访问,时间复杂度会是O(1)。所以这个效率是最高的。

class Solution {
public:
    bool isAnagram(string s, string t) {

        if (s.size() != t.size())
            return false;

        int *a = new int[26]();

        for (int i=0; i<s.size(); i++)
        {
            a[s[i]-'a']++;
            a[t[i]-'a']--;
        }

        for (int i=0; i<26; i++)
        {
            if (a[i] != 0)
                return false;
        }
        return true;


    }
};

但是,这个也要注意,就是适用于都是字母的,如果有Unicode字符,不适用。

发布了66 篇原创文章 · 获赞 67 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/wuzhongqiang/article/details/103289225
今日推荐