力扣刷题笔记(五)

今天开始刷字符串方面的算法题了。当然有些题目太简单了我就不拿出来了。

还是老规矩,一篇三题。前两三篇好像忘记把题目名字放出来了,这次记住了。

第一题:字符串中第一个单身字符

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

案例:

s = “leetcode”
返回 0.

s = “loveleetcode”,
返回 2.

注意事项:您可以假定该字符串只包含小写字母。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/first-unique-character-in-a-string
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。


第二题:有效的字母异位词

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

示例 1:

输入: s = “anagram”, t = “nagaram”
输出: true
示例 2:

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

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

来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/valid-anagram
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。


第三题:验证回文串

给定一个字符串,验证它是否是回文串,只考虑字母和数字字符,可以忽略字母的大小写。

说明:本题中,我们将空字符串定义为有效的回文串。

示例 1:

输入: “A man, a plan, a canal: Panama”
输出: true
示例 2:

输入: “race a car”
输出: false

来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/valid-palindrome
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。


我的题解(1)

看到这题呢,我又想巩固一下我的映射表方面的知识,所以我一开始是这样打算的:

在这里插入图片描述
看,本来是多好的思路啊,但是做的过程中发现map会根据键值大小自动排序。。。
我也不记得之前是谁跟我说map不提供自动排序的。。。

那就很尴尬了,于是我就决定暴力破解了。

但是也不是纯粹的暴力破解,还是有点技巧性的。
在这里插入图片描述

看一下代码:

int firstUniqChar(string s)
{
	//如果是空的
	if (s.size() == 0)
		return -1;

	vector<char> temp;

	string::iterator it1, it2;
	vector<char>::iterator vit;

	int flag;

	int count = 0;

	for (it1 = s.begin(); it1 != s.end(); it1++)
	{	
		flag = 1;
		for (vit = temp.begin(); vit != temp.end(); vit++)
		{
			if (*it1 == *vit)
			{
				flag = 0;
				count++;
				break;
			}
		}

		if (flag == 0)
			continue;

		it2 = it1;
		it2++;
		for (; it2 != s.end(); it2++)
		{
			//如果中间截胡了
			if (*it1 == *it2)
			{
				temp.push_back(*it1);
				flag = 0;
				break;
			}
		}

		if (flag == 0)	//如果截胡了
		{
			count++;
			continue;
		}
			
		//如果没有截胡
		return count;
	}

	//如果一个都没
	return -1;
}

我的题解(2)

这个简单的要死,只要不涉及位序,映射表就好了。图我就不画了。

bool isAnagram(string s, string t) 
{
	map<char, int> s_str,t_str;
	int count = 0;

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

	for (int i = 0; i < s.size(); i++)
	{
		s_str[s[i]] += 1;
		t_str[t[i]] += 1;
	}

	if (s_str.size() != t_str.size())
		return false;

	map<char, int>::iterator s_it = s_str.begin();
	map<char, int>::iterator t_it = t_str.begin();

	while (s_it != s_str.end())
	{
		if (s_it->first != t_it->first || s_it->second != t_it->second)
			return false;
		s_it++;
		t_it++;
	}
	return true;
}

我的题解(3)

这个第三题倒是好好的给我上了一课,倒不是说它很难,相反,还挺简单的。不过我发现迭代器好像没办法获取当前指向位置的下标吧!!!那就比较尴尬了,因为这题是不用遍历到尾的,只需要遍历到中间。

在这里插入图片描述

思路就是这么简单以至于官方都不给答案了。

那就看一下我的吧。

bool isPalindrome(string s) 
{
	string t;

	int a=0,b=0;
	int sz = s.size();

	//将字符串重组
	for (;a<sz; a++)
	{
		b = s[a];
		if ((97 <= b && 122 >= b) || (65 <= b && 90 >= b) || (48<=b && 57>=b))
			t.push_back(s[a]);
	}

	//头尾比对
	sz = t.size();

	for (a = 0,b = sz-1;a<b;a++,b--)
	{
		if (t[a] != t[b])
		{
			//要排掉数字
			if (57 >= t[a] || 57 >= t[b])
				return false;
			if (((t[a] - 32) != t[b]) && ((t[a] + 32) != t[b]))
				return false;
		}
	}
	return true;
}

官方题解(1)

方法一: 线性时间复杂度解法
这道题最优的解法就是线性复杂度了,为了保证每个元素是唯一的,至少得把每个字符都遍历一遍。

算法的思路就是遍历一遍字符串,然后把字符串中每个字符出现的次数保存在一个散列表中。这个过程的时间复杂度为 O(N)O(N),其中 NN 为字符串的长度。

接下来需要再遍历一次字符串,这一次利用散列表来检查遍历的每个字符是不是唯一的。如果当前字符唯一,直接返回当前下标就可以了。第二次遍历的时间复杂度也是 O(N)O(N)。

作者:LeetCode
链接:https://leetcode-cn.com/problems/first-unique-character-in-a-string/solution/zi-fu-chuan-zhong-de-di-yi-ge-wei-yi-zi-fu-by-leet/

来源:力扣(LeetCode) 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

说多了都是泪,散列表果然比映射表好用,进化了就是不一样。看来这次说什么也得会用哈希表!!!

class Solution {
    public int firstUniqChar(String s) {
        HashMap<Character, Integer> count = new HashMap<Character, Integer>();
        int n = s.length();
        // build hash map : character and how often it appears
        for (int i = 0; i < n; i++) {
            char c = s.charAt(i);
            count.put(c, count.getOrDefault(c, 0) + 1);
        }
        
        // find the index
        for (int i = 0; i < n; i++) {
            if (count.get(s.charAt(i)) == 1) 
                return i;
        }
        return -1;
    }
}

> 作者:LeetCode
> 链接:https://leetcode-cn.com/problems/first-unique-character-in-a-string/solution/zi-fu-chuan-zhong-de-di-yi-ge-wei-yi-zi-fu-by-leet/ 来源:力扣(LeetCode) 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

官方题解(2)

方法一:排序
算法:
通过将 ss 的字母重新排列成 tt 来生成变位词。因此,如果 TT 是 SS 的变位词,对两个字符串进行排序将产生两个相同的字符串。此外,如果 ss 和 tt 的长度不同,tt 不能是 ss 的变位词,我们可以提前返回。

作者:LeetCode
链接:https://leetcode-cn.com/problems/valid-anagram/solution/you-xiao-de-zi-mu-yi-wei-ci-by-leetcode/
来源:力扣(LeetCode) 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

方法二:哈希表
算法:

为了检查 tt 是否是 ss 的重新排列,我们可以计算两个字符串中每个字母的出现次数并进行比较。因为 SS 和 TT 都只包含 A-ZA−Z 的字母,所以一个简单的 26 位计数器表就足够了。
我们需要两个计数器数表进行比较吗?实际上不是,因为我们可以用一个计数器表计算 ss 字母的频率,用 tt 减少计数器表中的每个字母的计数器,然后检查计数器是否回到零。

作者:LeetCode
链接:https://leetcode-cn.com/problems/valid-anagram/solution/you-xiao-de-zi-mu-yi-wei-ci-by-leetcode/
来源:力扣(LeetCode) 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

我不觉得这题哈希表会比映射表要有优势。


官方题解(3)

应该是太简单而没有题解。


总结

做完这些题呢,应该明白以下几点:

  1. string串也是STL容器的一种。
  2. map容器会根据键值自动排序。
  3. 哈希表无论如何要掌握,尽快,希望明天就能马上学以致用。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章