Longest Palindromic Substring最大回文子串
考察字符串,分回文子串长度为奇数和回文子串长度为偶数两种情况考虑
#include <iostream>
using namespace std;
/**思路:
* 从回文串的对称点开始,依次向左向右比较,不相同的时候停止遍历,不断更新,直到找出最大的长度的回文子串。
* (1)回文子串长度为奇数:对称点只有一个字符
* (2)回文子串长度为偶数:对称点有两个字符
* 时间复杂度为O(n^2):对称点的数量为O(n),每次查找的时间也为O(n),所有总时间复杂度为O(n^2)
*/
class Solution {
public:
string longestPalindrome(string s) {
int len=s.length(); //字符串的长度
int i,left,right; //i是当前对称点
if(len==0)
return s;
string result="";
for(i=0;i<len;i++) //回文子串长度为奇数
{
left=right=i;
while(left>0 && right<len-1 && s[left-1]==s[right+1]) //对称,向左右移动
{
left--;
right++;
}
if(result.length()<right-left+1) //不断更新
result=s.substr(left,right-left+1);
}
for(i=0;i<len;i++)
{//回文子串长度为偶数
if(s[i]==s[i+1]){ //中心相等
left=i;
right=i+1;
while(left>0 && right<len-1 && s[left-1]==s[right+1]){ //对称,向左右移动
left--;
right++;
}
if(result.length()<right-left+1) //不断更新
result=s.substr(left,right-left+1);
}
}
return result;
}
};
int main()
{
string s="ccc";
Solution ss;
cout<<ss.longestPalindrome(s);
return 0;
}
Container With Most Water
#include <iostream>
#include <vector>
using namespace std;
/**思路:
* 从两边往中间找,每次放弃最短的板。
*从起点和终点开始找,宽度最大,这时每移动一次其中一个点,必然宽度变小。
*最大面积,只有高度增大才有可能做到,即放弃高度较小的点。
*/
class Solution {
public:
int maxArea(vector<int> &height) {
int area=0,h=0;
int i=1,j=height.size();
while(i!=j)
{
//min(height[i-1],height[j-1]):装多少水是由最短的板决定的
area=max(area,(j-i)*min(height[i-1],height[j-1]));
height[i-1]>height[j-1]?j--:i++;
}
return area;
}
};
int main()
{
vector<int> height={4,2,4,1,7,3,2};
Solution ss;
int area;
area=ss.maxArea(height);
cout<<area;
return 0;
}
3Sum
类比Two Sum
注:首先要注意排除重复;另外要注意排除重复时left和right的位置已经改变,所以使用res里的值
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
/**
* (1)首先用sort函数对数组进行排序(从小到大)
* (2)依次取出第 i 个数(i从0开始),并且不重复的选取(跳过重复的数)
* (3)这样问题就转换为 2 个数求和的问题(可以用双指针解决方法)
* 2 数求和问题
* (4)定义两个指针:左指针(left) 和 右指针(right)
* (5)找出固定 left, 此时left所指的位置为数组中最小数,再找到两个数和 不大于 target 的最大 right 的位置
* (6)调整 left 的位置(后移),求解和是否为 target O(n)
* (7)时间复杂度:O(nlogn) + O(n)
*/
class Solution {
public:
vector<vector<int>> threeSum(vector<int> &num) {
sort(num.begin(),num.end());//从小到大排序
vector<vector<int>> result; //存放返回结果
int left=0,right=0;
if(num.size()<3) return result;
for(int i=0;i<num.size();i++)
{
if(i!=0&&num[i]==num[i-1]) //防止重复
continue;
left=i+1;
right=num.size()-1;
while(left<right)
{
if(num[i]+num[left]+num[right]==0)
{
vector<int> res;
res.push_back(num[i]);
res.push_back(num[left]);
res.push_back(num[right]);
result.push_back(res);
left++;
right--;
//排除重复,用res,因为此时left和right都被改变了
//[-2,0,1,1,2]对应输出应该为:[[-2,0,2],[-2,1,1]]
while(left<right && num[left]==res[1]) left++;
while(left<right && num[right]==res[2]) right--;
}else if(num[i]+num[left]+num[right]>0){
right--; //排序了的数组,right--减小3sum
}else{
left++; //增大3sum
}
}
}
return result;
}
};
int main()
{
vector<int> s={-2,0,1,1,2};
Solution ss;
vector<vector<int>> result;
result=ss.threeSum(s);
for(int i=0;i<result.size();i++)
{
for(int k=0;k<result[i].size();k++)
cout<<result[i][k]<<",";
cout<<"\n";
}
return 0;
}