目录
longest-palindromic-substring(动态规划,中等)
anagrams(字典,中等)
给出一个字符串数组,返回所有互为“换位词(anagrams)”的字符串的组合。(换位词就是包含相同字母,但字母顺序可能不同的字符串)
For example:
Input: ["tea","and","ate","eat","den"]
Output: ["tea","ate","eat"]
思路
用字典来辅助,将每个值都排列好顺序后存入字典,如果下一个值排好序列之后和字典已经存进去的数相等,就说明这俩互为换位词。另外,字典的find用法,为true表示在字典中找到了重复的值,为false就是没找到。
m.find(key)!=m.end()
“-2”代表占位符,表示这个值之前已经遍历过了,不需要再考察了.
完整code
class Solution {
public:
vector<string> anagrams(vector<string> &strs) {
vector<string>res;
unordered_map<string,int>m;
for(int i=0;i<strs.size();i++)
{
string key=strs[i];
sort(key.begin(),key.end());
if(m.find(key)!=m.end())
{
if(m[key]!=-2)
res.push_back(strs[m[key]]);
m[key]=-2;
res.push_back(strs[i]);
}
else
m[key]=i;
}
return res;
}
};
implement-strstr(遍历,简单)
实现 strStr() 函数。
给定一个 haystack 字符串和一个 needle 字符串,在 haystack 字符串中找出 needle 字符串出现的第一个位置 (从0开始)。如果不存在,则返回 -1。
示例 1:
输入: haystack = "hello", needle = "ll"
输出: 2
示例 2:
输入: haystack = "aaaaa", needle = "bba"
输出: -1
思路
逐个元素对比,只要找到开头一样的,然后,就把needle循环对比一遍。
完整code
class Solution {
public:
char *strStr(char *haystack, char *needle) {
if(needle==NULL||haystack==NULL)
return NULL;
if(*haystack=='\0'&&*needle=='\0')
return haystack;
for(char *p=haystack;*p!='\0';p++)
{
char *l=p;
char *s=needle;
while(*l!='\0'&&*s!='\0'&&*l==*s)
{
l++;
s++;
}
if(*s=='\0')
return p;
}
return NULL;
}
};
zigzag-conversion(二维矩阵,中等)
将一个给定字符串根据给定的行数,以从上往下、从左到右进行 Z 字形排列。比如输入字符串为 "LEETCODEISHIRING" 行数为 3 时,排列如下:
L C I R
E T O E S I I G
E D H N
之后,你的输出需要从左往右逐行读取,产生出一个新的字符串,比如:"LCIRETOESIIGEDHN"。请你实现这个将字符串进行指定行数变换的函数:
string convert(string s, int numRows);
示例 1:
输入: s = "LEETCODEISHIRING", numRows = 3
输出: "LCIRETOESIIGEDHN"
示例 2:
输入: s = "LEETCODEISHIRING", numRows = 4
输出: "LDREOEIIECIHNTSG"
解释:
L D R
E O E I I
E C I H N
T S G
思路
这个和二维矩阵很相似,都是找关键位置和对应关系,进行移动,分三种情况,拐头
while (k < len)
{
res += s[k];
k += 2 * nRows - 2;
}
和Z字中间的元素移动,
bool flag = true;
while (k < len)
{
res += s[k];
k += flag ? 2 * (nRows - i - 1) : 2 * i;
flag =!flag;
}
设了一个标志位,表明后两种不同的区分。那对应关系是怎么得的,那我也说不清了,反正,就是有对应关系。
完整code
class Solution {
public:
string convert(string s, int nRows) {
if (nRows <= 1) return s;
string res = "";
int len = s.size();
for (int i = 0; i < nRows; i++)
{
int k = i;
if (i == 0 || i == nRows - 1)
{
while (k < len)
{
res += s[k];
k += 2 * nRows - 2;
}
}
bool flag = true;
while (k < len)
{
res += s[k];
k += flag ? 2 * (nRows - i - 1) : 2 * i;
flag =!flag;
}
}
return res;
}
};
longest-palindromic-substring(动态规划,中等)
给定一个字符串s,找到其中最长的回文子序列。可以假设s的最大长度为1000。
示例 1:
输入:"bbbab" 输出:4
一个可能的最长回文子序列为 "bbbb"。
示例 2:
输入:"cbbd" 输出:2
一个可能的最长回文子序列为 "bb"。
思路
fill_n函数的作用是:参数包括 : 一个迭代器,一个计数器以及一个值。该函数从迭代器指向的元素开始,将指定数量的元素设置为给定的值。
完整code
class Solution {
public:
// 最长回文串,使用dp
string longestPalindrome(string str)
{
int n = str.length();
if(n==0) return "";
bool dp[n][n];
fill_n(&dp[0][0],n*n,false);
int left=0,right=0,maxLen = 0;
for(int j=0;j<n;j++)
{
dp[j][j] = true;
for(int i=0;i<j;i++)
{
dp[i][j] = (str[i] == str[j] && (j-i < 2 || dp[i+1][j-1]));
if(dp[i][j] && (j-i+1 > maxLen))
{
left = i;
right = j;
maxLen = j-i+1;
}
}
}
return str.substr(left,right-left+1);
}
};
longest-common-prefix(遍历,简单)
编写一个函数来查找字符串数组中的最长公共前缀。
如果不存在公共前缀,返回空字符串 ""。
示例 1:
输入: ["flower","flow","flight"] 输出: "fl"
示例 2:
输入: ["dog","racecar","car"] 输出: ""
解释: 输入不存在公共前缀。
思路
先将开头首个字符串给作为待比较的值,让后面的每个字符都跟这个比较,将不重复的都删除。
如果说,就这一个字符串和其他的都没有公共部分,而其他的都有,算啥?算没公共字串,因为找公共字串是找所有的,少一个都不行。
完整code
class Solution {
public:
string longestCommonPrefix(vector<string>& strs) {
if (strs.empty()) return "";
string res = strs[0];
for (int i = 0; i < strs.size(); i++)
{
for (int j = 0; j < res.size(); j++)
{
if (res[j] == strs[i][j])
continue;
else
{
res.erase(j);
break;
}
}
}
return res;
}
};