leetcode 125、136、344、557、657、709、771、804、893、929

12 篇文章 1 订阅

Algorithm 1

125. 验证回文串

https://leetcode.com/problems/valid-palindrome/

1)problem

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

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

示例 1:

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

输入: "race a car"
输出: false

2)answer

1、普通思路

把数字和字符提取出来,然后如果是字母就转换为小写。加到新的字符串中。

对于这个新的字符串,使用一个多条件循环,分别从字符串头、字符串尾遍历字符串的中间值,如果不一致就退出。直到遍历结束还是一致就判定为回文字符串。

2、高级思路

在discuss看到的答案。

用一个大循环分别从字符串头、字符串尾遍历字符串的中间值,里面两个小循环,用isalnum()函数判断是不是字母数字,如果不是就向前移动指针。

https://leetcode.com/problems/valid-palindrome/discuss/119173/C+±Easy-to-Understand-Solution

3)solution

第一种方案:

先判断是否为数字字母,跟之前写的to-lower-case结合,把大写转换为小写。

#include<stdio.h>
#include <string>
using std::string;

class Solution {
public:
	bool isPalindrome(string s) {

		string re_val = "";
        // 除去特殊符号,提取出字符串的小写字母
		for (char str_val : s)
		{
			// 确认字母数字
			if (isalnum(str_val) != false)
			{
				if (str_val >= 'A'&& str_val <= 'Z')
				{
					// 取小写与大写之间的差值,得到字符对应的小写ASCII码对应是什么存进字符串中
					re_val += (str_val + ('a' - 'A'));
				}
				else
				{
					// 如果是小写就不处理
					re_val += str_val;
				}
			}
		}
		for (int i=0,j=re_val.size()-1; i<j;i++,j--) 
		{
			//一个指针从左边指到右边,一个指针从右边指向左边。如果有不同的值,就判断不是回文字符。
			if (re_val[i] != re_val[j])
				return false;
		}
    	return true;
	}
};


int main()
{

	Solution solu;
	bool ret;
	ret = solu.isPalindrome("A man, a plan, a canal: Panama");
	printf("%d \n", ret);
	ret = solu.isPalindrome("race a car");
	printf("%d \n", ret);
	return 0;
}

第二种方案:

bool isPalindrome(string s) {
    for (int i = 0, j = s.size() - 1; i < j; i++, j--) { // Move 2 pointers from each end until they collide
        while (isalnum(s[i]) == false && i < j) i++; // Increment left pointer if not alphanumeric
        while (isalnum(s[j]) == false && i < j) j--; // Decrement right pointer if no alphanumeric
        if (toupper(s[i]) != toupper(s[j])) return false; // Exit and return error if not match
    }
    
    return true;
}

Algorithm 2

136. Single Number

https://leetcode.com/problems/single-number/

1)problem

Given a non-empty array of integers, every element appears twice except for one. Find that single one.

Note:

Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory?

Example 1:

Input: [2,2,1]
Output: 1
Example 2:

Input: [4,1,2,1,2]
Output: 4

2)answer

数组中其他数出现两次,仅有一个出现一次的。逐个字符进行异或来,当某个数字出现第二次时候数字就归为0。二进制计算逻辑如下:

  二进制            异或      下一次的异或值   实际值    
4 ==> 100  ==>  100 ^ 000      = 100        = 4
1 ==> 001  ==>  001 ^ 100      = 101        = 5
2 ==> 010  ==>  010 ^ 101      = 111        = 7
1 ==> 001  ==>  001 ^ 111      = 110        = 6
2 ==> 010  ==>  010 ^ 110      = 100        = 4

3)solution

Cpp:

#include <stdio.h>
#include <vector>
using std::vector;


class Solution {
public:
    int singleNumber(vector<int>& nums) {
        
		int aNum = 0;
		for (int i = 0; i < nums.size(); i++) {
			aNum ^= nums[i];
		}
		return aNum;
    }
};

int main() 
{

	// 使用内容
	Solution nSolution;
	vector<int> nums;

	nums.push_back(2);
	nums.push_back(1);
	nums.push_back(2);
	nSolution.singleNumber(nums);
	return 0;
}

Python:

class Solution(object):
    def singleNumber(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        r_nums = 0
        for num in nums:
            r_nums ^= num
        return r_nums

4)总结

Tips:按tags刷会比较有效率。

  • String

https://leetcode.com/problemset/all/?topicSlugs=string

https://leetcode.com/problems/unique-email-addresses

https://leetcode.com/problems/to-lower-case

  • HASH Tables

https://leetcode.com/problems/jewels-and-stones

https://leetcode.com/problems/single-number

Algorithm 3

344. Reverse String

https://leetcode.com/problems/reverse-string/

1)problem

编写一个以字符串作为输入并逆转字符串的函数。

2)answer

字符串大于0,就从最末尾开始取值。

3)solution

#include "pch.h"
#include <stdio.h>
#include <string>
#include <iostream>
#include <algorithm>
using std::string;


class Solution {
public:
	string reverseString(string s) {

		string result = "";
		for (int i =s.length()-1;i>=0 ; i--)
		{
			result += s.at(i);
		}

		return result;

	}
};

int main()
{
	// 使用内容
	Solution nSolution;
	nSolution.reverseString("abcdef");
}

Algorithm 4

557. Reverse Words in a String III

https://leetcode.com/problems/reverse-words-in-a-string-iii/

1)problem

Given a string, you need to reverse the order of characters in each word within a sentence while still preserving whitespace and initial word order.

Example 1:

Input: "Let's take LeetCode contest"
Output: "s'teL ekat edoCteeL tsetnoc"

Note: In the string, each word is separated by single space and there will not be any extra space in the string.

2)answer

判断是否为空格,然后每个单词转换。有一个很好用的交换函数swap。

3)solution

class Solution {
public:
	string reverseWords(string s) {
		int begin = 0;
		int end = 0;
		for (int i = 0; i <= s.length(); ++i) {
			//如果遇到了空格,就准备颠倒每个字符串的值
			if (s[i] == ' ' || s[i] == '\0') {
				end = i;
				// 转换每个单词的值,end是单词的结尾长度,j是单词开始长度。
				for (int j = begin; j < end; ++j) {
					std::swap(s[j], s[--end]);
				}
				begin = i + 1;
			}
		}
		return s;
	}
};

Algorithm 5

657. Robot Return to Origin

https://leetcode.com/problems/robot-return-to-origin/

1)problem

There is a robot starting at position (0, 0), the origin, on a 2D plane. Given a sequence of its moves, judge if this robot ends up at (0, 0) after it completes its moves.

The move sequence is represented by a string, and the character moves[i] represents its ith move. Valid moves are R (right), L (left), U (up), and D (down). If the robot returns to the origin after it finishes all of its moves, return true. Otherwise, return false.

Note: The way that the robot is "facing" is irrelevant. "R" will always make the robot move to the right once, "L" will always make it move left, etc. Also, assume that the magnitude of the robot's movement is the same for each move.

机器人从位置(0,0)开始,在2D平面上开始。给定一系列动作,判断该机器人在完成动作后是否在(0,0)结束。

移动序列由字符串表示,字符move [i]表示其第i个移动。有效移动是R(右),L(左),U(上)和D(下)。如果机器人在完成所有移动后返回原点,则返回true。否则,返回false。

注意:机器人“面对”的方式无关紧要。“R”将始终使机器人向右移动一次,“L”将始终向左移动等。此外,假设每次移动机器人的移动幅度相同。

Example 1:

Input: "UD"
Output: true 
Explanation: The robot moves up once, and then down once. All moves have the same magnitude, so it ended up at the origin where it started. Therefore, we return true.

机器人向上移动一次,然后向下移动一次。所有动作都具有相同的幅度,因此它最终位于它开始的原点。因此,我们回归真实。

Example 2:

Input: "LL"
Output: false
Explanation: The robot moves left twice. It ends up two "moves" to the left of the origin. We return false because it is not at the origin at the end of its moves.

机器人向左移动两次。它最终在原点的左边有两个“移动”。我们返回false,因为它不是在它移动结束时的原点。

2)answer

只需要两个变量记录水平方向和垂直方向是否最后处在原点即可;

3)solution

#include "pch.h"
#include <iostream>
#include <string>
using std::string;

class Solution {
public:
	bool judgeCircle(string moves) {
		int y = 0;
		int x = 0;

		for (int i = 0; i<moves.length();i++)
		{
			switch (moves.at(i))
			{
			    case 'U':{ y++; } break;
				case 'D':{ y--; } break;
				case 'L':{ x--; } break;
				case 'R': {x++; } break;
			default:
				break;
			}
		}
		if (x == 0 && y == 0)
		{
			return  true;
		}
		return false;

	}
};

int main()
{
    std::cout << "Hello World!\n"; 

	Solution s;
	s.judgeCircle("UD");
}

Algorithm 6

做一个 leetcode 的算法题

709. To Lower Case

https://leetcode.com/problems/to-lower-case/

1)problem

Implement function ToLowerCase() that has a string parameter str, and returns the same string in lowercase.

Example 1:
    Input: "Hello"
    Output: "hello"
Example 2:
    Input: "here"
    Output: "here"
Example 3:
    Input: "LOVELY"
    Output: "lovely"

2)answer

声明一个新的字符串变量,对传入的字符串的字符逐个读取,如果是大写字母就取小写与大写之间的差值,得到大写字符对应的小写字母ASCII码存进字符串中。处理完后返回结果。

3)solution

Cpp:

#include <stdio.h>
#include <string>
using std::string;


class Solution {
public:
	string toLowerCase(string str) {
		string re_val = "";
		for (char str_val : str)
		{
			if (str_val >='A'&& str_val <='Z')
			{
				// 取小写与大写之间的差值,得到字符对应的小写ASCII码对应是什么存进字符串中
				re_val += (str_val + ('a' - 'A'));
			}
			else
			{
				// 如果是小写就不处理
				re_val += str_val;
			}

		}
		return re_val;

	}
};

int main() 
{

	// 使用内容
	Solution nSolution;
	nSolution.toLowerCase("hello World?");
	return 0;
}

Python:

class Solution(object):
    def toLowerCase(self, str):
        """
        :type str: str
        :rtype: str
        """
        ret = ""
        for s in str:
            if s>='A' and s<='Z':
                ret += chr(ord(s)+(ord('a')- ord('A')))
            else:
                ret +=s
                
        return ret

Algorithm 7

做一个 leetcode 的算法题

771. Jewels and Stones

https://leetcode.com/problems/jewels-and-stones/

1)problem

ou’re given strings J representing the types of stones that are jewels, and S representing the stones you have. Each character in S is a type of stone you have. You want to know how many of the stones you have are also jewels.

The letters in J are guaranteed distinct, and all characters in J and S are letters. Letters are case sensitive, so “a” is considered a different type of stone from “A”.

Example 1:

Input: J = "aA", S = "aAAbbbb"
Output: 3

Example 2:

Input: J = "z", S = "ZZ"
Output: 0

Note:

  • S and J will consist of letters and have length at most 50.
  • The characters in J are distinct.

2)answer

设定一个数字变量,判断单个字符是否在一个字符串中。使用双重for循环进行判断,如果相同就将数字变量加1,否则就跳过。最后返回数字变量的值就是手中宝石的数量。

3)solution

#include<stdio.h>
#include <string>
using std::string;

class Solution {
public:
	int numJewelsInStones(string J, string S) {
		int num = 0;
		for (auto J_value : J)
		{
			for (auto S_value : S)
			{
				if (J_value==S_value)
				{
					num++;
				}
			}
		}

		return num;
	}
};


int main() 
{
	Solution solu;
	int ret;
    ret  = solu.numJewelsInStones("aA", "aAAbbbb");
	printf("%d \n", ret);
	ret = solu.numJewelsInStones("z", "ZZ");
	printf("%d \n", ret);
	return 0;
}

Algorithm 8

804. Unique Morse Code Words

https://leetcode.com/problems/unique-morse-code-words/

1)problem

International Morse Code defines a standard encoding where each letter is mapped to a series of dots and dashes, as follows: "a" maps to ".-", "b" maps to "-...", "c" maps to "-.-.", and so on
For convenience, the full table for the 26 letters of the English alphabet is given below:

[".-","-...","-.-.","-..",".","..-.","--.","....","..",".---","-.-",".-..","--","-.","---",".--.","--.-",".-.","...","-","..-","...-",".--","-..-","-.--","--.."]

Now, given a list of words, each word can be written as a concatenation of the Morse code of each letter. For example, "cba" can be written as "-.-..--...", (which is the concatenation "-.-." + "-..." + ".-"). We'll call such a concatenation, the transformation of a word.

Return the number of different transformations among all words we have.

Example:
    Input: words = ["gin", "zen", "gig", "msg"]
    Output: 2
    Explanation: 
    The transformation of each word is:
    "gin" -> "--...-."
    "zen" -> "--...-."
    "gig" -> "--...--."
    "msg" -> "--...--."

There are 2 different transformations, "--...-." and "--...--.".

Note:
    The length of words will be at most 100.
    Each words[i] will have length in range [1, 12].
    words[i] will only consist of lowercase letters.

2)answer

将26个因为字母映射为摩斯电码,然后根据每组字母每个字符对应的摩斯电码组合起来。至于那个简写是为什么可以那么写,没搞清楚。【“cba” can be written as “-.-…–…”, (which is the concatenation “-.-.” + “-…” + “.-”).】

3)solution

#include "pch.h"
#include <stdio.h>
#include <string>
#include <vector>
#include <unordered_set>
using std::string;
using std::vector;
using std::unordered_set;


class Solution {
public:
	int uniqueMorseRepresentations(vector<string>& words) {
		vector<string> morse_code = { ".-","-...","-.-.","-..",".","..-.","--.","....","..",".---","-.-",".-..","--","-.","---",".--.","--.-",".-.","...","-","..-","...-",".--","-..-","-.--","--.." };
		// vector<string> store;
		unordered_set<string> result_val;
		int count = 0;
		for (auto str: words)
		{
			string tmp;
			for (auto ch: str)
			{
				//-'a'是找到输入字的索引。例如,'a' - 'a'为0.所以'a'对应于morse_code中的第一个元素。
				tmp += morse_code[(int)ch - (int)('a')];
			}

			result_val.insert(tmp);

		}
		return result_val.size();
	}
};

int main()
{
	vector<string> words;
	words.push_back("cba");
	// 使用内容
	Solution nSolution;
	nSolution.uniqueMorseRepresentations(words);
}

Algorithm 9

893. Groups of Special-Equivalent Strings

https://leetcode.com/problems/groups-of-special-equivalent-strings/

1)problem

You are given an array A of strings.

Two strings S and T are special-equivalent if after any number of moves, S == T.

A move consists of choosing two indices i and j with i % 2 == j % 2, and swapping S[i] with S[j].

Now, a group of special-equivalent strings from A is a non-empty subset S of A such that any string not in S is not special-equivalent with any string in S.

Return the number of groups of special-equivalent strings from A.

Example 1:

Input: ["a","b","c","a","c","c"]
Output: 3
Explanation: 3 groups ["a","a"], ["b"], ["c","c","c"]

Example 2:

Input: ["aa","bb","ab","ba"]
Output: 4
Explanation: 4 groups ["aa"], ["bb"], ["ab"], ["ba"]

Example 3:

Input: ["abc","acb","bac","bca","cab","cba"]
Output: 3
Explanation: 3 groups ["abc","cba"], ["acb","bca"], ["bac","cab"]

Example 4:

Input: ["abcd","cdab","adcb","cbad"]
Output: 1
Explanation: 1 group ["abcd","cdab","adcb","cbad"]

Note:

  • 1 <= A.length <= 1000
  • 1 <= A[i].length <= 20
  • All A[i] have the same length.
  • All A[i] consist of only lowercase letters.

2)answer

统计奇数位和偶数位的个字符出现的次数,如果 S0 串和 S1 串统计的结果相同,则它们是 special-equivalent 的。

3)solution

  1. 将字符串拆分为两个子字符串,1个包含偶数索引字符,1个包含奇数字符串
  2. 对两个子字符串进行排序(这样做是因为如果可以将字符串与另一个字符串交换,那么在排序时它们将彼此相等,因为它们必须具有相同的字符)
  3. 将一对字符串插入集合中,这将跟踪唯一的“组”
  4. 重新调整集合的大小

符合上面两个条件的是一组。

参考:https://blog.csdn.net/g_r_c/article/details/82079678

unordered_set使用方法

.find() 返回一个迭代器。这个迭代器指向和参数哈希值匹配的元素,如果没有匹配的元素,会返回这个容器的结束迭代器。
.end() 返回指向容器末尾位置的迭代器
.insert() 插入元素 

视频:

https://www.youtube.com/watch?v=WJ4NtyrakT0&feature=youtu.be

图片示例:

C++实现代码:

#include "pch.h"
#include <iostream>
#include <string>
#include <vector>
#include <unordered_set>
#include <algorithm>
using std::vector;
using std::string;
using std::unordered_set;

class Solution {
public:
	int numSpecialEquivGroups(vector<string>& A) {
		unordered_set<string> st;
		for (int i = 0; i < A.size(); ++i) {
			string odd = "";
			string even = "";
			for (int j = 0; j < A[i].size(); ++j) {
				// 奇偶位的值
				if (j % 2 == 0)
					odd += A[i][j];
 				else
					even += A[i][j];
			}
			// 排序奇偶位的值
			sort(odd.begin(), odd.end());
			sort(even.begin(), even.end());
			st.insert(odd + even);
			
 		}
		return st.size();
	}
};
int main()
{
	Solution solution;
	vector<string> A1 = { "abcd", "cdab", "adcb", "cbad" };
	vector<string> A2 = { "abc", "acb", "bac", "bca", "cab", "cba" };
	int res1 = solution.numSpecialEquivGroups(A1);
	int res2 = solution.numSpecialEquivGroups(A2);
}

Python实现:

def numSpecialEquivGroups(self,A):
    s = set()
    for w in A:
        even = ''.join(sorted(w[0::2]))
        odd  = ''.join(sorted(w[1::2]))
        s.add(odd+even)
    return len(s)

Algorithm 10

929. Unique Email Addresses

https://leetcode.com/problems/unique-email-addresses/

1)problem

929. Unique Email Addresses

Every email consists of a local name and a domain name, separated by the @ sign.

For example, in alice@leetcode.com, alice is the local name, and leetcode.com is the domain name.

Besides lowercase letters, these emails may contain '.'s or '+'s.

If you add periods ('.') between some characters in the local name part of an email address, mail sent there will be forwarded to the same address without dots in the local name.  For example, "alice.z@leetcode.com" and "alicez@leetcode.com" forward to the same email address.  (Note that this rule does not apply for domain names.)

If you add a plus ('+') in the local name, everything after the first plus sign will be ignored. This allows certain emails to be filtered, for example m.y+name@email.com will be forwarded to my@email.com.  (Again, this rule does not apply for domain names.)

It is possible to use both of these rules at the same time.

Given a list of emails, we send one email to each address in the list.  How many different addresses actually receive mails? 

Example 1:

Input: ["test.email+alex@leetcode.com","test.e.mail+bob.cathy@leetcode.com","testemail+david@lee.tcode.com"]
Output: 2
Explanation: "testemail@leetcode.com" and "testemail@lee.tcode.com" actually receive mails

Note:

1 <= emails[i].length <= 100
1 <= emails.length <= 100
Each emails[i] contains exactly one '@' character.

2)answer

试题是希望过滤每个邮件中的【.】符号,忽略第一个【+】后面的所有内容。

在网上搜索到用Python的题解:

class Solution(object):
    def numUniqueEmails(self, emails):
        unique_emails = set()
        
        for email in emails:
            local_name, domain_name = email.split('@')
            local_name = local_name.replace('.', '')
            local_name = local_name.split('+')[0]
            modified_email = local_name + '@' + domain_name
            unique_emails.add(modified_email)
            
        return len(unique_emails)

设定一个集合变量,先是提取出邮件名与域名,然后过滤掉所有的【.】号。选择所有加号前的第一个索引值,然后把邮件名和域名合并在一起加入集合变量里。返回集合变量的数值就是实际发送数量。

3)solution

用C++做起来要复杂一点。

  • 1、提取【@】符号前面的内容,得到邮件名
  • 2、替换掉所有【.】符号,得到实际邮件名
  • 3、提取出【+】符号前的内容,得到发送的邮件名
  • 4、将邮件名与域名合并成实际发送的邮件地址
#include "pch.h"
#include <stdio.h>
#include <string>
#include <vector>
#include <set>
#include <iostream>
#include <algorithm>
using std::string;
using std::vector;
using std::set;


class Solution {
public:
	int numUniqueEmails(vector<string>& emails) {
        //集合中包含的元素值是唯一的。
		set<string> email_sets;
		for (string email : emails)
		{
			// 提取邮件名
			int pos = email.find('@');
			string local_name = email.substr(0, pos);
			// 过滤掉【.】符号
			// remove:从给定范围中消除指定值,而不影响剩余元素的顺序,并返回不包含指定值的新范围的末尾。
			// 从string中删除所有某个特定字符
			local_name.erase(std::remove(local_name.begin(), local_name.end(), '.'), local_name.end());
			// 提取【+】符号前的字符
			pos = local_name.find('+');
			local_name = local_name.substr(0, pos);
			// 提取【@】后的域名
			pos = email.find('@');
			string domain_name = email.substr(pos + 1);
            // 合并实际发送的邮件名称
			email = local_name + '@' + domain_name;
			// 写进集合中
			email_sets.insert(email);

		}
        // 返回集合大小
		return email_sets.size();
	}
};


int main()
{ 
	//vector初始化字符串
	vector<string> emails;

	emails.push_back("test.email+alex@leetcode.com");
	emails.push_back("test.e.mail+bob.cathy@leetcode.com");
	emails.push_back("testemail+david@lee.tcode.com");

	// 使用内容
	Solution nSolution;
	nSolution.numUniqueEmails(emails);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值