Give two nonnegative integers in string form num1 and Num2, return num1 and num2 Their products are also expressed in string form.
Example 1:
Input: num1 = "2", num2 = "3"
Output: "6"
Example 2:
Input: num1 = "123", num2 = "456"
Output: "56088"
explain:
num1 and num2 The length of is less than 110.
num1 and num2 contains only numbers 0-9.
num1 and num2 Do not start with zero unless it is the number 0 itself.
You cannot use the large number type of any standard library (such as BigInteger) or directly convert the input to an integer.
Original idea:
1. Convert a string into an array 2. Multiply the corresponding bits 3. Change the result to a string
(corresponding bit multiplication is not thought clearly, that is, how to multiply, and zero filling mentioned later)
Train of thought correction:
Method 1: add
1. If one of num 1 and num2 is 0, you can directly return 0 as the result.
2. If neither num 1 nor num2 is 0, it is calculated by vertical multiplication.
Traverse the multiplier from left to right, multiply each bit of the multiplier (num2) by the multiplicand (num1) to obtain the corresponding result, and then accumulate the results obtained each time
num2 processes the lowest bit, and the operation result of each other bit needs to be supplemented with 0
class Solution { public: string multiply(string num1, string num2) { //0 if (num1 == "0" || num2 == "0") { return "0"; } string ans = "0"; int m = num1.size(), n = num2.size(); //Traverse num2 from left to right for (int i = n - 1; i >= 0; i--) { string curr; int add = 0;//carry for (int j = n - 1; j > i; j--) { curr.push_back(0);//push_back() adds an element at the end of the Vector (the parameter is the value to be inserted), where 0 is added } int y = num2.at(i) - '0';//String. At() is used to get the specified character; at(i),i is the subscript of the character you want to get, and the return value of the function is the specified character //Traverse num1 for (int j = m - 1; j >= 0; j--) { int x = num1.at(j) - '0'; int product = x * y + add;//Multiplication + carry curr.push_back(product % 10);//Reserved remainder add = product / 10;//carry } while (add != 0) { curr.push_back(add % 10); add /= 10; } reverse(curr.begin(), curr.end()); // The reverse function is used to reverse the order within the range of [first, last] (including the elements pointed to by first, excluding the elements pointed to by last). The reverse function does not return a value for (auto &c : curr) { c += '0';//Zero filling } ans = addStrings(ans, curr); } return ans; } string addStrings(string &num1, string &num2) { int i = num1.size() - 1, j = num2.size() - 1, add = 0; string ans; while (i >= 0 || j >= 0 || add != 0) { int x = i >= 0 ? num1.at(i) - '0' : 0; int y = j >= 0 ? num2.at(j) - '0' : 0; int result = x + y + add; ans.push_back(result % 10); add = result / 10; i--; j--; } reverse(ans.begin(), ans.end()); for (auto &c: ans) { c += '0'; } return ans; } };// 8ms
Two functions: multiply(string num1, string num2); and addstrings (string & num1, string & num2); implement addition and carry functions respectively
Special functions used:
push_back(): add an element at the end of the Vector (the parameter is the value to be inserted).
String. At(): get the specified character; at(i), i is the subscript of the character you want to get, and the return value of the function is the specified character
Reverse(): reverses the order within the range of [first, last] (including the elements pointed to by first, excluding the elements pointed to by last). The reverse function does not return a value
Ternary operator:
Method 2: multiplication
Storing results with arrays instead of strings
Let m and N represent the lengths of num1 and num2 respectively, and neither of them is 0, then the length of their product is m+n-1 or m+n
This creates an array ansArr of length m+n to store the product
num 1[i] × The result of num2[j] is located in ansArr[i+j+1]. If ansArr[i+j+1] ≥ 10, the carry part is added to ansArr[i+j]
class Solution { public: string multiply(string num1, string num2) { if (num1 == "0" || num2 == "0") { return "0"; } int m = num1.size(), n = num2.size(); auto ansArr = vector<int>(m + n);//Store product, size m+n //Traverse num1 for (int i = m - 1; i >= 0; i--) { int x = num1.at(i) - '0'; //Traversal num2 for (int j = n - 1; j >= 0; j--) { int y = num2.at(j) - '0'; ansArr[i + j + 1] += x * y;//product } } for (int i = m + n - 1; i > 0; i--) { ansArr[i - 1] += ansArr[i] / 10;//Top ten (to the first) ansArr[i] %= 10;//The remainder exists in this bit } int index = ansArr[0] == 0 ? 1 : 0; string ans; while (index < m + n) { ans.push_back(ansArr[index]); index++; } for (auto &c: ans) { c += '0'; } return ans; } };//4ms
Give you a string array, please combine the letter ectopic words together. You can return the result list in any order.
An alphabetic ectopic word is a new word obtained by rearranging the letters of the source word. All the letters in the source word are used just once.
Example 1:
Input: strs = ["eat", "tea", "tan", "ate", "nat", "bat"]
Output: ["bat"],["nat","tan"],["ate","eat","tea"]]
Example 2:
Input: strs = [""]
Output: [""]]
Example 3:
Input: strs = ["a"]
Output: ["a"]]
Tips:
1 <= strs.length <= 104
0 <= strs[i].length <= 100
strs[i] Contains only lowercase letters
The meaning of the title is: put the words with the same letters in an array
Key points: how to recognize the letters of each word? First, make it clear that the string needs to be transformed into an array
Method 1: sorting
1. Convert different strings into character arrays and sort them alphabetically
2. The sorted results of ectopic words are the same, so they can be used as the key value of the hash table
3. Take the set composed of alphabetic ectopic words as the value value of the hash table
java version:
class Solution { public List<List<String>> groupAnagrams(String[] strs) { //Determine whether it is an empty string array if(strs == null || strs.length == 0){ return new ArrayList(); } //1. Create a hash table Map<String,List> map = new HashMap<String, List>(); for (String s: strs) { //Convert string to character array char[] chars = s.toCharArray(); //Sort the character array alphabetically Arrays.sort(chars); //The sorted string is used as the key value in the hash table String key = String.valueOf(chars); //2. Judge whether the key value exists in the hash table if (!map.containsKey(key)){ //If it does not exist, it will be a new ectopic word and create a new key value pair in the map map.put(key,new ArrayList()); } //3. Put the string in the list of the corresponding key map.get(key).add(s); } //Returns a list of all key value objects in the map return new ArrayList(map.values()); } }
c + + version
class Solution { public: vector<vector<string>> groupAnagrams(vector<string>& strs) { unordered_map<string, vector<string>> mp; //Construct word character sort as key for (string& str: strs) { string key = str; sort(key.begin(), key.end());//sort mp[key].emplace_back(str); } vector<vector<string>> ans; //Add the corresponding position of hash table for (auto it = mp.begin(); it != mp.end(); ++it) { ans.emplace_back(it->second); } return ans; } };
Method 2: counting
Since the two strings of mutually alphabetic ectopic words contain the same letters, the occurrence times of the same letters in the two strings must be the same. Therefore, the occurrence times of each letter can be represented by a string as the key of the hash table.
Because strings contain only lowercase letters, you can use an array of length 26 to record the number of occurrences of each letter for each string.
class Solution { public: vector<vector<string>> groupAnagrams(vector<string>& strs) { // Customize the hash function for array < int, 26 > auto arrayHash = [fn = hash<int>{}] (const array<int, 26>& arr) -> size_t { return accumulate(arr.begin(), arr.end(), 0u, [&](size_t acc, int num) { return (acc << 1) ^ fn(num); }); }; unordered_map<array<int, 26>, vector<string>, decltype(arrayHash)> mp(0, arrayHash); for (string& str: strs) { array<int, 26> counts{}; int length = str.length(); for (int i = 0; i < length; ++i) { counts[str[i] - 'a'] ++; } mp[counts].emplace_back(str); } vector<vector<string>> ans; for (auto it = mp.begin(); it != mp.end(); ++it) { ans.emplace_back(it->second); } return ans; } };
Method 3: violent solution
class Solution { public List<List<String>> groupAnagrams(String[] strs) { List<List<String>> result = new ArrayList<>(); int len = strs.length; String[] strings = new String[len]; //Put the sorted dest string array into a new string array for (int i = 0; i < len; i++) { byte[] bytes = strs[i].getBytes(); Arrays.sort(bytes); strings[i] = new String(bytes); } //Traverse the new string array and classify the same string (the classified string can be set to null) for (int i = 0; i < len; i++) { ArrayList<String> strings1 = new ArrayList<>(); //If it is blank, it indicates that it has been classified if (strings[i] != null) { strings1.add(strs[i]); //Find the same string after sorting for (int j = i + 1; j < len; j++) { if (strings[i].equals(strings[j])) { strings1.add(strs[j]); // The classified string is left blank strings[j] = null; } } } //Put the classified string group into the result set if (strings1.size() != 0) result.add(strings1); } return result; } }
Method 4: hash table solution
1. Prepare several bucket s to store the original string after grouping
2. Find the bucket according to the sorted string and put the original string into the bucket
The sorted string is used as the key, and the sorted string findbucke is used
After traversing the string array, the grouping is completed
3. Put the sub result set in each bucket into the final result set
class Solution { public: vector<vector<string>> groupAnagrams(vector<string>& strs) { unordered_map<string, vector<string>> mp; vector<vector<string>> result;//Result set //Sort; put the corresponding original string into the bucket for(auto str : strs) { auto tempStr = str; sort(tempStr.begin(), tempStr.end()); mp[tempStr].push_back(str); } //Put into result set for(auto elem : mp) { result.push_back(elem.second); } return result; } };
Summary:
Once you need to classify according to characteristics, use hash table
In fact, the idea of this classification problem can be determined: the first traversal should be divided into categories, and the second time can be taken out as ans.
Then, the key selection idea is the core. Each question may have the characteristics of each question.
For this question, after sorting, the disordered strings can be divided into one category
class Solution { public: vector<vector<string>> groupAnagrams(vector<string>& strs) { unordered_map<string,vector<string>> mymap; for( int i=0; i<strs.size() ;i++ ) { string str = strs[i]; sort( str.begin() , str.end() );//sort mymap[str].push_back( strs[i] ); } vector<vector<string>> ans;//Result set for(auto it = mymap.begin() ;it!= mymap.end() ;it++ ) { ans.push_back(it->second); } return ans; } };