1.两数之和
利用哈希表进行操作,使用哈希表可以用空间换时间,达到目的
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
unordered_map<int,int> hash;
for(int i=0;i<nums.size();i++){
int temp = target - nums[i];
if(hash.find(temp)!=hash.end()){
return{hash[temp],i};
}
hash[nums[i]] = i;
}
return {};
}
};
2.两数相加
1:直接新建节点用于保存结果
class Solution {
public:
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
ListNode* head = new ListNode(-1);
ListNode* move = head;
int sum = 0 ;
bool carry = false;
while(l1!=NULL||l2!=NULL){
sum = 0;
if(l1!=NULL){
sum+=l1->val;
l1 = l1->next;
}
if(l2!=NULL){
sum+=l2->val;
l2 = l2 ->next;
}
if(carry){
sum++;
}
move->next = new ListNode(sum%10);
move = move->next;
carry = sum>9?true:false;
}
if(carry)move->next = new ListNode(1);
return head->next;
}
};
2.选用最长链表作为最后结果链表
3.无重复字符的最长子串
1.查找strat end 间是否存在end+1 否则更新end length
class Solution {
public:
int lengthOfLongestSubstring(string s) {
int start=0,end=0;
int result=0;
int length=0;
int len = s.size();
char temp;
while(end<len){
temp = s[end];
for(int i =start;i<end;i++){
if(s[i]==temp){
start = i+1;
length = end - start;
break;
}
}
end++;
length++;
result = max(result,length);
}
return result;
}
};
2.利用哈希表优化查找
5.回文子串
动态规划:
注意动态规划三要素
class Solution {
public:
string longestPalindrome(string s) {
int len = s.size();
if(len<2)return s;
vector<vector<int>>dp(len,vector<int>(len));
int max=1,start=0;
for(int i=0;i<len;i++){
dp[i][i] = 1;
if((i<len-1)&&s[i]==s[i+1]){
dp[i][i+1] = 1;
max=2;
start = i;
}
}
for(int l=3;l<=len;l++){
for(int i=0;i+l-1<len;i++){
int j = i+l-1;
if(s[i]==s[j]&&(dp[i+1][j-1]==1)){
dp[i][j]=1;
max = l;
start = i;
}
}
}
return s.substr(start,max);
}
};
6.z字变换
充分利用题目规律进行。设置向下flag
class Solution {
public:
string convert(string s, int numRows) {
if(numRows==1)return s;
vector<string> row(numRows);
int cur_row=0,go_down = 0;
for(char c:s){
row[cur_row]+=c;
if(cur_row==0||cur_row==numRows-1)go_down=!go_down;
cur_row+=go_down?1:-1;
}
string res;
for(string temp:row){
res+=temp;
}
return res;
}
};
7.反转整数
本题需考虑溢出问题,将末尾数字分别找出,之后累加即可
class Solution {
public:
int reverse(int x) {
int res=0;
while(x!=0){
int pop = x%10;
x/=10;
if(res>INT_MAX/10||(res==INT_MAX/10&&pop>7))return 0;
if(res<INT_MIN/10||(res == INT_MIN/10&&pop<-9))return 0;
res = res*10 + pop;
}
return res;
}
};
8.字符串转整数
class Solution {
public:
int myAtoi(string str) {
int i=0,flag=1;
while(str[i]==' ')i++;
if(str[i]=='-')flag=0;
if(str[i]=='-'||str[i]=='+')i++;
int res=0;
while(i<str.size()&&isdigit(str[i])){
int temp = str[i]-'0';
if(res>INT_MAX/10||(res==INT_MAX/10&&temp>7)){
return flag?INT_MAX:INT_MIN;
}
res = res*10+temp;
i++;
}
return flag?res:-res;
}
};
9.回文数字判断
代码:将数字反转即可
class Solution {
public:
bool isPalindrome(int x) {
if(x<0)return false;
int temp;
long res=0;
int y=x;
while(x!=0){
temp = x%10;
res = res*10 + temp;
x /=10;
}
return y==res?true:false;
}
};
10.正则表达式判断
利用优秀的动态规划
class Solution {
public:
bool isMatch(string s, string p) {
bool dp[s.size()+1][p.size()+1];//s的前i字符是否能被p的前j字符匹配
dp[0][0]=true;
//初始化
for(int i=0;i<p.size();i++){
if(p[i]=='*' && dp[0][i-1])dp[0][i+1]=true;
else dp[0][i+1]=false;
}
if(s.size()>0){
for(int i=1;i<=s.size();i++){
dp[i][0]=false;
}
}
//dp迭代
for(int i=0;i<s.size();i++){
for(int j=0;j<p.size();j++){
if(s[i]==p[j] || p[j]=='.')dp[i+1][j+1]=dp[i][j];
else if(p[j]=='*'){
if(p[j-1]!='.'&&p[j-1]!=s[i])
dp[i+1][j+1]=dp[i+1][j-1];
else{
if(dp[i][j+1] || dp[i+1][j] || dp[i+1][j-1])dp[i+1][j+1]=true;//当*匹配1个多个或零个时
else dp[i+1][j+1]=false;
}
}
else dp[i+1][j+1]=false;
}
}
return dp[s.size()][p.size()];
}
};
11.盛最多水的容器
代码:主要利用双指针法,较为简单
class Solution {
public:
int maxArea(vector<int>& height) {
int left=0,right=height.size()-1;
int res;
res = (right-left)*min(height[left],height[right]);
while(left<right){
if(height[left]<height[right])left++;
else right--;
res = max(res,(right-left)*min(height[left],height[right]));
}
return res;
}
};
12.整数转罗马数字
直接将所有结果写出即可:
class Solution {
public:
string intToRoman(int num) {
int values[] = {1000,900,500,400,100,90,50,40,10,9,5,4,1};
string re[] = {"M","CM","D","CD","C","XC","L","XL","X","IX","V","IV","I"};
string out;
for(int i=0;i<13;i++){
while(num>=values[i]){
num-=values[i];
out+=re[i];
}
}
return out;
}
};
14.最长公共前缀
代码:比较各个字符串的同一位置的值是否相同
class Solution {
public:
string longestCommonPrefix(vector<string>& strs) {
if(strs.size()==0)return {""};
for(int i=0;i<strs[0].size();i++){
for(int j=1;j<strs.size();j++){
if(i==strs[j].size()||strs[0][i]!=strs[j][i]){
return strs[0].substr(0,i);
}
}
}
return strs[0];
}
};
15.三数之和
利用双指针法:
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
sort(nums.begin(),nums.end());
int len = nums.size();
vector<vector<int>> ans;
int left=0,right=0;
for(int i=0;i<len-2;i++){
if(i>0&&nums[i]==nums[i-1])continue;
left=i+1;
right = len-1;
while(left<right){
if(nums[i]+nums[left]+nums[right]==0){
ans.push_back({nums[i],nums[left],nums[right]});
left++;
right--;
while(left<right&&nums[left]==nums[left-1])left++;
while(left<right&&nums[right]==nums[right+1])right--;
}
else if(nums[i]+nums[left]+nums[right]>0)right--;
else left++;
}
}
return ans;
}
};
16.最接近的三数之和
代码:利用三指针法,与15类似
class Solution {
public:
int threeSumClosest(vector<int>& nums, int target) {
sort(nums.begin(),nums.end());
int result=nums[0] + nums[1] + nums[2],left=0,right=nums.size()-1;
for(int i=0;i<nums.size()-2;i++){
left=i+1;
right=nums.size()-1;
while(left<right){
int temp=nums[i]+nums[left]+nums[right];
if(abs(temp-target)<abs(result-target))result=temp;
if(temp>target)right--;
else if(temp<target) left++;
else return target;
}
}
return result;
}
};