LeetCode-Hash Table

来源:互联网 发布:powerdesigner mac 编辑:程序博客网 时间:2024/05/29 09:03

(LeetCode持续更新中…)

409. Longest Palindrome(最长回文数)

Given a string which consists of lowercase or uppercase letters, find the length of the longest palindromes that can be built with those letters.
This is case sensitive, for example “Aa” is not considered a palindrome here.
Note:
Assume the length of given string will not exceed 1,010.

Example:

Input:
“abccccdd”
Output:
7
Explanation:
One longest palindrome that can be built is “dccaccd”, whose length is 7.

解析:

字符串中找能形成最长的回文串,有哪些字符可以加入到回文串?
(1)出现偶数次的字符,必然可以加入回文串;“aaaacd”->”aaaa”
(2)出现次数大于1且不是偶数,则将该其拆分成 “偶数+1”,其中偶数字符必然可以加入回文串,”aaabb”->”abba”; 剩下的一个字符,要加入回文串,有一个前提条件,那就是没有“没有 出现过1次的字符 已经加入过回文串”,”aaabbc”->”ababa”;
(3)只出现1次的字符,能加入回文串的前提是“没有 出现过1次的字符 已经加入过回文串”,“aabbcd”->”aacbb”或者”aadbb”

C++实现:

class Solution {public:    int longestPalindrome(string s) {        unordered_map<char,int> table;        for(int i=0; i<s.length(); ++i){            table[s[i]]++;        }        unordered_map<char,int>::iterator it = table.begin();        int result = 0;        bool isOne = false; //记录只出现过1次的字符是否加入过回文串        int temp = 0;        for( ; it!=table.end(); it++){            temp = it->second;            if(temp%2==0)               result +=  temp;             else if(temp>1){                result += temp-1;                if(!isOne){                    isOne = true;                    result += 1;                }             }             else if(temp==1 && !isOne){                 result += 1;                 isOne = true;             }        }        return result;    }};

349. Intersection of Two Arrays(两个数组的交集)

Given two arrays, write a function to compute their intersection.

Example:

Given nums1 = [1, 2, 2, 1], nums2 = [2, 2], return [2].

Note:

Each element in the result must be unique.
The result can be in any order.

解析:

(1)第一种方法,暴力法,两个for循环,时间复杂度为O(m*n);
(2)第二种方法,分别对两个数组排序,然后用两个指针指向两个有序数组,通过移位比对,找到两个数组的交集,时间复杂度为O(NlogN)+O(MlogM)+O(m+n);
(3)第三种方法,用hash,推荐使用unordered_map\unordered_set,这两个HashTable可以在常数时间内进行查找、插入、删除元素。具体:将array1放入map,遍历array2,判断元素是否在map,如果在,则将该元素放入结果集,同时在map中删除该元素(防止同一元素重复插入结果集)。

C++实现:
(1)使用unordered_set

class Solution {public:    vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {        unordered_set<int> table(nums1.begin(),nums1.end());        vector<int> result;        for(auto a:nums2){    //auto会根据初始值自动判断变量类型            if(table.count(a)==1){                result.push_back(a);                table.erase(a);            }        }        return result;    }};

(2)使用unordered_map

class Solution {public:    vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {        unordered_map<int,int> table;        for(auto a:nums1){            table[a] = 1;        }        vector<int> result;        for(auto a:nums2){            if(table.count(a)==1){                result.push_back(a);                table.erase(a);            }        }        return result;    }};

350. Intersection of Two Arrays II(求两个数组的交集)

Given two arrays, write a function to compute their intersection.

Example:

Given nums1 = [1, 2, 2, 1], nums2 = [2, 2], return [2, 2].

Note:

Each element in the result should appear as many times as it shows in both arrays.The result can be in any order.

Follow up:

What if the given array is already sorted? How would you optimize your algorithm?
What if nums1’s size is small compared to nums2’s size? Which algorithm is better?
What if elements of nums2 are stored on disk, and the memory is limited such that you cannot load all elements into the memory at once?

c++实现:

class Solution {public:    vector<int> intersect(vector<int>& nums1, vector<int>& nums2) {        unordered_multiset<int> table(nums1.begin(),nums1.end());        vector<int> result;        for(auto a:nums2){    //auto会根据初始值自动判断变量类型            if(table.count(a)>0){                result.push_back(a);                table.erase(table.find(a));            }        }        return result;    }};

438. Find All Anagrams in a String

Given a string s and a non-empty string p, find all the start indices of p’s anagrams in s.
Strings consists of lowercase English letters only and the length of both strings s and p will not be larger than 20,100.
The order of output does not matter.

Example 1:

Input:
s: “cbaebabacd” p: “abc”
Output:
[0, 6]
Explanation:
The substring with start index = 0 is “cba”, which is an anagram of “abc”.
The substring with start index = 6 is “bac”, which is an anagram of “abc”.

Example 2:

Input:
s: “abab” p: “ab”
Output:
[0, 1, 2]
Explanation:
The substring with start index = 0 is “ab”, which is an anagram of “ab”.
The substring with start index = 1 is “ba”, which is an anagram of “ab”.
The substring with start index = 2 is “ab”, which is an anagram of “ab”.

解析:

(1)方法一:将字符串s切割成长度为|p|的子串,对比子串和p中的字符,时间复杂度为O(N*N);
(2)方法二:将字符串p的字符放入hash表,定义两个指针left和right,初始指向s的第一个字符,count设为p的长度,然后每次向右移动right指针,判断s[right]是否在hash表中,如果在,则count减一,当count==0时,表明left开头的子串是p的变形,将left加入结果集中,然后left向右移动,循环指导right指向s的末尾。

C++实现:

class Solution {public:    vector<int> findAnagrams(string s, string p) {         vector<int> result;        if(s.length()==0 || p.length()==0 || s.length()<p.length())            return result;        int hash[256];          //最多有256个字符        for(int i=0; i<256; ++i)            hash[i] = 0;        for(auto a : p)            hash[a]++;        int left=0, right=0, count=p.length();        while(right<s.length()){            //move right everytime, if the character exists in p's hash, decrease the count           //current hash value >= 1 means the character is existing in p            if(hash[s[right++]]-- >0)                count--;            //when the count is down to 0, means we found the right anagram            //then add window's left to result list                if(count==0)                result.push_back(left);            //if we find the window's size equals to p, then we have to move left (narrow the window) to find the new match window            //++ to reset the hash because we kicked out the left            //only increase the count if the character is in p            //the count >= 0 indicate it was original in the hash, cuz it won't go below 0            if((right-left)==p.length() && hash[s[left++]]++>=0)                count++;        }        return result;    }};

290. Word Pattern(字符模式匹配)

Given a pattern and a string str, find if str follows the same pattern.
Here follow means a full match, such that there is a bijection between a letter in pattern and a non-empty word in str.

Examples:

pattern = “abba”, str = “dog cat cat dog” should return true.
pattern = “abba”, str = “dog cat cat fish” should return false.
pattern = “aaaa”, str = “dog cat cat dog” should return false.
pattern = “abba”, str = “dog dog dog dog” should return false.

Notes:

You may assume pattern contains only lowercase letters, and str contains lowercase letters separated by a single space.

解析:

需要注意一下几个情况:
(1)pattern或str为空
(2)pattern中的字符数,少于 str中的空格分割后字段数
(3)abba->”dog dog dog dog”

C++代码实现:

class Solution {public:    bool wordPattern(string pattern, string str) {        if(pattern.length()==0 && str.length()>0)            return false;        if(pattern.length()>0 && str.length()==0)            return false;        if(pattern.length()==0 && str.length()==0)            return true;        unordered_map<char,string> hash;        unordered_map<string,int> values;        int index = 0,begin=0;        string temp;        for(auto a : pattern){            index = str.find(" ",begin);            temp = str.substr(begin,index-begin);            begin = index+1;            if(!hash.count(a)){                hash[a] = temp;                if(!values.count(temp))     //防止出现a->dog,b->dog的情况                    values[temp]++;                else                    return false;            }else{               if(strcmp(temp.c_str(),hash[a].c_str())!=0)                return false;            }        }        if(str[begin-1]==' ')   //防止str中字段数多于pattern的字符数量            return false;        return true;    }};

205. Isomorphic Strings

Given two strings s and t, determine if they are isomorphic.
Two strings are isomorphic if the characters in s can be replaced to get t.
All occurrences of a character must be replaced with another character while preserving the order of characters. No two characters may map to the same character but a character may map to itself.

For example,

Given “egg”, “add”, return true.
Given “foo”, “bar”, return false.
Given “paper”, “title”, return true.

Note:

You may assume both s and t have the same length.

C++代码实现:

class Solution {public:    bool isIsomorphic(string s, string t) {        int len1 = s.length();        int len2 = t.length();        if(len1==0 && len2>0)            return false;        if(len1>0 && len2==0)            return false;        if(len1==0 && len2==0)            return true;        if(len1!=len2)            return false;        unordered_map<char,char> hash;        unordered_map<char,int> values;        for(int i=0; i<len1; i++){            if(!hash.count(s[i])){                hash[s[i]] = t[i];                if(!values.count(t[i]))                    values[t[i]]++;                else                    return false;            }else{                if(t[i]!=hash[s[i]])                    return false;            }        }        return true;    }};

508. Most Frequent Subtree Sum

Given the root of a tree, you are asked to find the most frequent subtree sum. The subtree sum of a node is defined as the sum of all the node values formed by the subtree rooted at that node (including the node itself). So what is the most frequent subtree sum value? If there is a tie, return all the values with the highest frequency in any order.

Examples 1

Input:
5
/ \
2 -3
return [2, -3, 4], since all the values happen only once, return all of them in any order.

Examples 2

Input:
5
/ \
2 -5
return [2], since 2 happens twice, however -5 only occur once.

Note: You may assume the sum of values in any subtree is in the range of 32-bit signed integer.

解析:

递归遍历左右子树,分别求出左右子树和

C++代码实现:

/** * Definition for a binary tree node. * struct TreeNode { *     int val; *     TreeNode *left; *     TreeNode *right; *     TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */class Solution {public:    vector<int> findFrequentTreeSum(TreeNode* root) {        unordered_map<int,int> subTreeSum;        vector<int> result;        if(root==NULL)            return result;        int rootSum = root->val;        if(root->left!=NULL);            rootSum += getSubTreeSum(root->left,subTreeSum);        if(root->right!=NULL)            rootSum += getSubTreeSum(root->right,subTreeSum);        subTreeSum[rootSum]++;        vector<pair<int,int> > tempVector(subTreeSum.begin(),subTreeSum.end());        sort(tempVector.begin(),tempVector.end(),Solution::cmp_by_value);        auto it = tempVector.begin();        int max = it->second;        result.push_back(it->first);        it++;        for( ; it!=tempVector.end(); ++it){            if(max==it->second)                result.push_back(it->first);            else                break;        }        return result;    }    int getSubTreeSum(TreeNode *node,unordered_map<int,int> &subTreeSum){        if(node==NULL)            return 0;        int sum = node->val;         if(node->left!=NULL);            sum += getSubTreeSum(node->left,subTreeSum);        if(node->right!=NULL)            sum += getSubTreeSum(node->right,subTreeSum);        subTreeSum[sum]++;        return sum;    }    bool static cmp_by_value(const pair<int,int>& a, const pair<int,int>& b) {        return a.second > b.second;    }};

30. Substring with Concatenation of All Words

You are given a string, s, and a list of words, words, that are all of the same length. Find all starting indices of substring(s) in s that is a concatenation of each word in words exactly once and without any intervening characters.

For example, given:

s: “barfoothefoobarman”
words: [“foo”, “bar”]
You should return the indices: [0,9].
(order does not matter).

解析:

(1)方法一:统计words的单词出现次数到map中,遍历s,每次取长度为wordlen*num的子串,将子串分割成单词w,看w出现是否出现在map中及其出现次数,如果不出现或者出现次数大于map中记录次数,则说明子串包含了不属于words的单词。否则,将该子串下标加入结果集。时间复杂度为O(N*m),m为words单词个数。
(2)方法二:移动窗口,(来源于LeetCode)travel all the words combinations to maintain a window, there are wl(word len) times travel; each time, n/wl words, mostly 2 times travel for each word,one left side of the window, the other right side of the window;时间复杂度为O(n*k),k为words中单词长度。
举个例子:
比如s = “a1b2c3a1d4”L={“a1”,“b2”,“c3”,“d4”}
窗口最开始为空,
a1在L中,加入窗口 【a1】b2c3a1d4
b2在L中,加入窗口 【a1b2】c3a1d4
c3在L中,加入窗口 【a1b2c3】a1d4
a1在L中了,但是前面a1已经算了一次,此时只需要把窗口向右移动一个单词a1【b2c3a1】d4
d4在L中,加入窗口a1【b2c3a1d4】找到了一个匹配
如果把s改为“a1b2c3kka1d4”,那么在第四步中会碰到单词kk,kk不在L中,此时窗口起始位置移动到kk后面a1b2c3kk【a1d4】

C++代码实现:
方法一:

class Solution {public:    vector<int> findSubstring(string s, vector<string>& words) {        vector<int> result;        int len = s.length();        int num = words.size();        int wordlen = words[0].length();        if(num==0 || len==0)            return result;       int substrLen = wordlen*num;        if(s.length()<substrLen)            return result;        unordered_map<string,int> wordCount;        for(string word : words)            wordCount[word]++;        for(int i=0; i<len-substrLen+1; i++){            unordered_map<string,int> seen;            int j = 0;            for(; j<num; j++){                string word = s.substr(i+j*wordlen,wordlen);                if(wordCount.count(word)==1){                    seen[word]++;                    if(seen[word]>wordCount[word])                        break;                }                else                    break;            }            if(j==num)                result.push_back(i);        }        return result;    }};

方法二:

class Solution {public:    vector<int> findSubstring(string s, vector<string>& words) {        vector<int> result;        int len = s.length();        int num = words.size();        int wordlen = words[0].length();        if(num==0 || len==0)            return result;       int substrLen = wordlen*num;        if(s.length()<substrLen)            return result;        unordered_map<string,int> wordCount;        for(string word : words)            wordCount[word]++;        for (int i = 0; i < wordlen; ++i) {            //left窗口起始位置,count当前窗口单词个数            int left = i, count = 0;            //tdict当前窗口中单词出现次数            unordered_map<string, int> tdict;            for (int j = i; j <= (len - wordlen); j += wordlen) {                //移动窗口为[left,j]                string str = s.substr(j, wordlen);                // a valid word, accumulate results                if (wordCount.count(str)) {                    tdict[str]++;                    if (tdict[str] <= wordCount[str])                         count++;                    else {                        //当前的单词在map中,但是它已经在窗口中出现了相应的次数,不应该加入窗口,此时,应该把窗口起始位置想左移动到,该单词第一次出现的位置的下一个单词位置                        while (tdict[str] > wordCount[str]) {                            string str1 = s.substr(left, wordlen);                            tdict[str1]--;                            if (tdict[str1] < wordCount[str1]) count--;                            left += wordlen;                        }                    }                    // come to a result                    if (count == num) {                        result.push_back(left);                        // advance one word                        tdict[s.substr(left, wordlen)]--;                        count--;                        left += wordlen;                    }                }                // not a valid word, reset all vars                else {                    tdict.clear();                    count = 0;                    left = j + wordlen;                }            }        }        return result;    }};

76. Minimum Window Substring

Given a string S and a string T, find the minimum window in S which will contain all the characters in T in complexity O(n).

example

S = “ADOBECODEBANC”
T = “ABC”
Minimum window is “BANC”.

Note:

If there is no such window in S that covers all characters in T, return the empty string “”.
If there are multiple such windows, you are guaranteed that there will always be only one unique minimum window in S.

解析:

(1)方法一:暴力法,假定子串步长step,然后从0开始依次取长度为step的串substr,判断T中的字符是否都出现在substr中,如果没有,step++,循环。时间复杂度为O(N*N)。超时!!!
(2)方法二:移动窗口和双指针,设定两个指针slow和fast,[slow,fast]代表窗口,窗口即为包含了T中所有字符的一个S的子串substr。用count记录T中字符出现次数,如果count>T.size,则说明此时[slow,fast]形成了一个窗口,然后通过移动slow指针,不断缩小窗口;每次找到一个更小的窗口fast-slow+1小于min,更新结果。具体实现见代码。
(3)方法三:万能法,可解决大部分“substring”问题,本质和方法2类似,代码比方法二少很多。下面是算法模板:

int findSubstring(string s){        unordered_map<char,int> map(128,0);        int counter; // check whether the substring is valid        int begin=0, end=0; //two pointers, one point to tail and one  head        int d; //the length of substring        for() { /* initialize the hash map here */ }        while(end<s.size()){            if(map[s[end++]]-- ?){  /* modify counter here */ }            while(/* counter condition */){                  /* update d here if finding minimum*/                //increase begin to make it invalid/valid again                if(map[s[begin++]]++ ?){ /*modify counter here*/ }            }              /* update d here if finding maximum*/        }        return d;  }

The code of solving Longest Substring Without Repeating Characters is below:

int lengthOfLongestSubstring(string s) {        vector<int> map(128,0);        int counter=0, begin=0, end=0, d=0;         while(end<s.size()){            if(map[s[end++]]++>0) counter++;             while(counter>0) if(map[s[begin++]]-->1) counter--;            d=max(d, end-begin); //while valid, update d        }        return d;    }

C++代码实现:
方法一:暴力法

class Solution {public:    string minWindow(string s, string t) {        string result = "";        int lenS = s.length();        int lenT = t.length();        if(lenS==0 || lenT==0 || lenS<lenT)            return result;        unordered_map<char,int> dict;        for(char c : t)            dict[c]++;        int dictSize = dict.size();        int step = lenT;        //步长        for(int i=0; i<=(lenS-lenT); i++){            unordered_map<char,int> tdict;            int count = 0;            for(int j=0; j<=(lenS-step); j++){                string substr = s.substr(j,step);                for(char c : substr){                    if(dict.count(c))    //字符存在                        tdict[c]++;                }                for(auto it=dict.begin(); it!=dict.end(); it++){                    if(tdict[it->first]>=it->second)                        count++;                    else                        break;                }                if(count==dictSize)                    return substr;                count = 0;                tdict.clear();            }            step++;        }        return result;    }};

方法二:移动窗口+双指针

class Solution {public:    string minWindow(string s, string t) {        string result = "";        int lenS = s.length();        int lenT = t.length();        if(lenS==0 || lenT==0 || lenS<lenT)            return result;        unordered_map<char,int> dict;        unordered_map<char,int> window;        for(char c : t)            dict[c]++;        int minLen = INT_MAX;        int count = 0;        int slow = 0,fast = 0;        for(; fast<lenS; fast++){            char c = s[fast];            if(dict.count(c)){                window[c]++;                if(window[c]<=dict[c])                    count++;            }            if(count>=lenT){                while(!dict.count(s[slow]) || window[s[slow]]>dict[s[slow]]){                    window[s[slow]]--;                    slow++;                }                if((fast-slow+1)<minLen){                    minLen = fast-slow+1;                    result = s.substr(slow,minLen);                }            }        }        return result;    }};

方法三:hashmap+two pointers(推荐)

class Solution {public:    string minWindow(string s, string t) {        string result;        int lenS = s.length();        int lenT = t.length();        if(lenS==0 || lenT==0 || lenS<lenT)            return result;        unordered_map<char,int> dict;        for(char c : t)            dict[c]++;        int counter=t.size(), begin=0, end=0, d=INT_MAX, head=0;        while(end<s.size()){            if(dict[s[end++]]-->0) counter--; //in t            while(counter==0){ //valid                if(end-begin<d)  d=end-(head=begin);                if(dict[s[begin++]]++==0) counter++;  //make it invalid            }        }        return d==INT_MAX? "":s.substr(head, d);        return result;    }};

37. Sudoku Solver

Write a program to solve a Sudoku puzzle by filling the empty cells.
Empty cells are indicated by the character ‘.’.
You may assume that there will be only one unique solution.
这里写图片描述

解析:

回溯法:每一个空格从1-9试探是否可以填入。

C++代码实现:

class Solution {public:    void solveSudoku(vector<vector<char>>& board) {        if(board.empty() || board.size()<9)            return;        backtrack(board,0);    }private:    bool backtrack(vector<vector<char>>& board,int position){  //从空格的候选项中选择一个候选者,然后不断回溯        if(position>=81)            //9*9            return true;        int row = position/9;        int col = position%9;        if(board[row][col]!='.')            return backtrack(board,position+1);        else{            for(char c='1'; c<='9'; c++){                if(checkBoard(board,row,col,c)){                    board[row][col] = c;                    if(!backtrack(board,position+1))                        board[row][col] = '.';                    else                        return true;                }            }        }        return false;    }    bool checkBoard(const vector<vector<char>>& board,int row,int col,char c){        return checkInRow(board,row,c) && checkInCol(board,col,c) && checkInCell(board,row,col,c);    }    bool checkInRow(const vector<vector<char>>& board,int row,char c){        for(int i=0; i<9; i++){            if(board[row][i]==c){                return false;            }        }        return true;    }    bool checkInCol(const vector<vector<char>>& board,int col,char c){        for(int i=0; i<9; i++){            if(board[i][col]==c){                return false;            }        }        return true;    }    bool checkInCell(const vector<vector<char>>& board,int row,int col,char c){       int startRow = (row/3)*3;       int startCol = (col/3)*3;       for(int i=startRow; i<(startRow+3); ++i){           for(int j=startCol; j<(startCol+3); ++j){               if(board[i][j]==c)                    return false;           }       }       return true;    }};

149. Max Points on a Line

Given n points on a 2D plane, find the maximum number of points that lie on the same straight line.

解析:

给定n个点,寻找包含点最多的直线。基本思路是对集合中任意两个点对,构建直线。
判断A B C三个点是否在一条直线上,通过AB与AC的斜率来判断。斜率的表示可以是double和pair(int,int),double在计算时容易丢失精度,所以这里推荐使用pair(int,int)。 时间复杂度O(n^2)。

C++代码实现:

/** * Definition for a point. * struct Point { *     int x; *     int y; *     Point() : x(0), y(0) {} *     Point(int a, int b) : x(a), y(b) {} * }; */class Solution {public:    int maxPoints(vector<Point>& points) {        int count = points.size();        if(count<=2)            return count;        int result = 2;              //至少有两个点        for(int i=0; i<count; ++i){            int same = 1,infinitySlop=0;            map<pair<int,int>,int> lines;                                //记录不同的行            for(int j=i+1; j<count; ++j){                if(points[i].x==points[j].x && points[i].y==points[j].y)    //与point[i]相同的点                    same++;                else if(points[i].x==points[j].x)                           //斜率无穷大                    infinitySlop++;                else{                    int a = points[i].x-points[j].x;                    int b = points[i].y-points[j].y;                    int g = gcd(a,b);                    a /= g;                    b /= g;                    lines[make_pair(a,b)]++;                }            }            int currentMax = infinitySlop;            for(auto it = lines.begin(); it!=lines.end(); ++it){                currentMax = (currentMax > it->second)? currentMax : it->second;            }            currentMax += same;            result = (result > currentMax)? result : currentMax;        }        return result;    }    int gcd(int a,int b) {        int r = 0;        while(b!=0){            r = a%b;            a = b;            b = r;        }        return a;    }};

336. Palindrome Pairs

Given a list of unique words, find all pairs of distinct indices (i, j) in the given list, so that the concatenation of the two words, i.e. words[i] + words[j] is a palindrome.

Example 1:

Given words = [“bat”, “tab”, “cat”]
Return [[0, 1], [1, 0]]
The palindromes are [“battab”, “tabbat”]

Example 2:

Given words = [“abcd”, “dcba”, “lls”, “s”, “sssll”]
Return [[0, 1], [1, 0], [3, 2], [2, 4]]
The palindromes are [“dcbaabcd”, “abcddcba”, “slls”, “llssssll”]

解析:

(1)暴力法。对任意两个单词w1\w2,判断w1+w2 和 w2+w1是否是回文串。算法复杂度为O(n^2)。容易超时
(2)hashmap法。用hashmap <string,int>记录词及下标。w1和w2构成回文串有以下几种情况:

  • 如果w1为“”,如果w2是回文串,则w1+w2 和 w2+w1都是回文串;
  • 如果w2是w1的反转字符串,则w1+w2 和 w2+w1都是回文串;
  • 如果w1[0 : cut]是回文串,且w2是w1[cut+1 : ]的反转字符串,则 w2+w1是回文串;
  • 如果w1[cut+1:]是回文串,且w2是w1[0 : cut]的反转字符串,则 w1+w2是回文串;

C++代码实现:

class Solution {public:    vector<vector<int>> palindromePairs(vector<string>& words) {        vector<vector<int>> result;        int wordCount = words.size();        if(wordCount<=1)            return result;        unordered_map<string,int> dict;        for(int i=0; i<wordCount; ++i)            dict[words[i]] = i;        //第一种情况        if(dict.count("")){            int index = dict[""];            for(int i=0; i<wordCount; ++i){                if(i==index)                    continue;                if(isPalindrome(words[i])){                    result.push_back({index,i});                    result.push_back({i,index});                }            }        }        //第二种情况        for(int i=0; i<wordCount; ++i){            string reverseWord = words[i];            reverse(reverseWord.begin(),reverseWord.end());            if(dict.count(reverseWord)){                int index = dict[reverseWord];                if(i==index)                    continue;                //result.push_back({index,i}); //防止重复计算                result.push_back({i,index});            }        }        //第三、四种情况        for(int i=0; i<wordCount; ++i){            for(int j=1; j<words[i].length(); ++j){                string w1 = words[i].substr(0,j);                if(isPalindrome(w1)){                    string w2 = words[i].substr(j);                    reverse(w2.begin(), w2.end());                    if(dict.count(w2)){                        int index = dict[w2];                        result.push_back({index,i});                    }                }                w1 = words[i].substr(j);                if(isPalindrome(w1)){                    string w2 = words[i].substr(0,j);                    reverse(w2.begin(), w2.end());                    if(dict.count(w2)){                        int index = dict[w2];                        result.push_back({i,index});                    }                }            }        }        return result;    }private:    bool isPalindrome(const string& word){        int len = word.length();        int end = len>>1;        for(int i=0; i<=end; ++i){            if(word[i]!=word[len-1-i])                return false;        }        return true;    }};
原创粉丝点击