3. Longest Substring Without Repeating Characters
Given a string, find the length of the longest substring without repeating characters.
Examples:
Given "abcabcbb"
, the answer is "abc"
, which the length is 3.
Given "bbbbb"
, the answer is "b"
, with the length of 1.
Given "pwwkew"
, the answer is "wke"
, with the length of 3. Note that the answer must be a substring, "pwke"
is a subsequence and not a substring.
class Solution {
public:
int lengthOfLongestSubstring(string s) {
unordered_set<char> storedChar;
int n=s.size();
if(n<=1) return n;
int sum=1;
for(int i=0;i<n;i++)
{
int j=0;
int tempsum=1;
storedChar.insert(s[i]);
for(int j=i+1;j<n;j++)
{
if(storedChar.find(s[j])!=storedChar.end())
{
storedChar.clear();
break;
}
else
{
tempsum++;
storedChar.insert(s[j]);
}
}
if(sum<tempsum) sum=tempsum;//这个要放在判断语句的外边,才能保证都执行到
if(j==n) break;//如果已经有一个遍历到最后,那后面没有再遍历的必要了
}
return sum;
}
};
双指针+哈希表(固定数组)
大神解法1:时间复杂度是n,空间复杂度是常数。这种方法实际上是双指针的方法。因为只有256个字符,定义一个256长度的矩阵,矩阵中存储每个字符最后出现的位置。
定义一个变量start,这个变量的初始值是-1,它保存的是当前字符之前最后一个重复字符的第一个字符的位置。如aabbc,如果当前遍历到c,那么start保存的是第一个b的位置。
class Solution {
public:
int lengthOfLongestSubstring(string s) {
vector<int> de(256,-1);
int result=0;
int j=-1;
for(int i=0;i<s.size();i++)
{
if(de[s[i]]>j)//如果之前有重复的字符,这里使用大于号,为了移动j指针到最新的重复值上去。
j=de[s[i]];
de[s[i]]=i;
result =max(result,i-j);
}
return result;
}
};
最多推荐解法:
与上面的方法基本上一样,只不过使用的是哈希表,变量的初始值也不是0,将第二个指针移动到最近的重复字符,最左边的右边一个位置。这种方法更容易理解题目使用双指针和哈希表的原理。
这里编程需要注意的是,由于map的特点,还没有存储的字符默认的键值是0,所以为了与初始零位区别,存储的键值从1开始算。
另外一个需要注意的是:判断移动j指针的条件需要仔细考虑。
class Solution {
public:
int lengthOfLongestSubstring(string s) {
unordered_map<char,int> decide;//键是字符,值是标号的位置
int n=s.size();
int result=0;
int j=0;
for(int i=0;i<n;i++)
{
if(decide[s[i]]>j)//注意这里的判断条件
j=decide[s[i]];
decide[s[i]]=i+1;
result=max(result,i-j+1);
}
return result;
}
};
7. Reverse Integer
Reverse digits of an integer.
Example1: x = 123, return 321
Example2: x = -123, return -321
14.Longest Common Prefix 舍弃
class Solution {
public:
string longestCommonPrefix(vector<string>& strs) {
int n=strs.size();
string result;
if(n==0) return result;
string flag=strs[0];
int m=flag.size();
for(int i=0;i<m;i++)
{
for(int j=1;j<n;j++)
{
if(flag[i]!=strs[j][i])
return result;
}
result.push_back(flag[i]);
}
return result;
}
};
20. Valid Parentheses 有效括号
Given a string containing just the characters '('
, ')'
, '{'
, '}'
, '['
and ']'
, determine if the input string is valid.
The brackets must close in the correct order, "()"
and "()[]{}"
are all valid but "(]"
and "([)]"
are not.
思路,依次将这些字符入栈,判断栈顶元素与当前元素是否是对应上的,是则pop,不是则入栈,到最后判断栈是否为空。
class Solution {
public:
bool isValid(string s) {
stack<char> result;
int n=s.size();
if(n==0) return true;
for(int i=0;i<n;i++)
{
if(result.empty())
result.push(s[i]);
else if(result.top()=='('&&s[i]==')'||
result.top()=='['&&s[i]==']'||
result.top()=='{'&&s[i]=='}')
result.pop();
else
result.push(s[i]);
}
return result.empty();
}
};
别人的思路:
这种方法能够更快的判断不符合条件的字符串,不需要将字符串遍历完成。
class Solution {
public:
bool isValid(string s) {
stack<char> paren;
for (char& c : s) {
switch (c) {
case '(':
case '{':
case '[': paren.push(c); break;
case ')': if (paren.empty() || paren.top()!='(') return false; else paren.pop(); break;
case '}': if (paren.empty() || paren.top()!='{') return false; else paren.pop(); break;
case ']': if (paren.empty() || paren.top()!='[') return false; else paren.pop(); break;
default: ; // pass
}
}
return paren.empty() ;
}
};
注意:只要当前的字符是)}]三个的一个,如果不能与栈顶结合,那就说明这个字符串是错误的。比如下面的代码。
class Solution {
public:
bool isValid(string s) {
stack<char> result;
for(auto & a:s){
if(a=='(') result.push(')');
else if(a=='{') result.push('}');
else if(a=='[') result.push(']');
else if(result.empty()||result.top()!=a)//这里直接出栈判断
return false;
else result.pop();
}
return result.empty();
}
};
38. Count and Say
The count-and-say sequence is the sequence of integers with the first five terms as following:
1. 1 2. 11 3. 21 4. 1211 5. 111221
1
is read off as "one 1"
or 11
.
11
is read off as "two 1s"
or 21
.
21
is read off as "one 2
, then one 1"
or 1211
.
Given an integer n, generate the nth term of the count-and-say sequence.
Note: Each term of the sequence of integers will be represented as a string.
Example 1:
Input: 1 Output: "1"
Example 2:
Input: 4 Output: "1211"根据题意写的代码
class Solution {
public:
string countAndSay(int n) {
string res;
res+=to_string(1);
if(n==1) return res;
for(int i=2;i<=n;i++)
{
string temp;
int num=1;
for(int j=0;j<res.size();j++)
{
while(j+1!=res.size())
{
if(res[j]==res[j+1])
{
j++;
num++;
}
else break;
}
temp+=to_string(num);
temp+=to_string(res[j]);//错误处在这
//改:temp+=res[j];
num=1;
}
res=temp;
}
return res;
}
};
69. Sqrt(x)
Implement int sqrt(int x)
.
Compute and return the square root of x.
这个题目的意思是找到一个整数的整数平方根。412. Fizz Buzz
Write a program that outputs the string representation of numbers from 1 to n.
But for multiples of three it should output “Fizz” instead of the number and for the multiples of five output “Buzz”. For numbers which are multiples of both three and five output “FizzBuzz”.
Example:
n = 15,
Return:
[
"1",
"2",
"Fizz",
"4",
"Buzz",
"Fizz",
"7",
"8",
"Fizz",
"Buzz",
"11",
"Fizz",
"13",
"14",
"FizzBuzz"
]
class Solution {
public:
vector<string> fizzBuzz(int n) {
vector<string> result;
string five="Buzz";
string three="Fizz";
string fth="FizzBuzz";
for(int i=1;i<=n;i++)
{
if(i%3==0&&i%5==0) result.push_back(fth);
else if(i%3==0) result.push_back(three);
else if(i%5==0) result.push_back(five);
else
{
string temp;
temp+=to_string(i);//记住这个用法
result.push_back(temp);
}
}
return result;
}
};
简单的代码,下面的代码使用string的+特性,少一个判断。初始化时,string是空的。
class Solution {
public:
vector<string> fizzBuzz(int n) {
vector<string> result(n);
for(int i=1;i<=n;i++)
{
if(i%3==0) result[i-1]+="Fizz";
if(i%5==0) result[i-1]+="Buzz";
if(result[i-1].empty())
result[i-1]+=to_string(i);
}
return result;
}
};