我流分级:
Easy 做出来的题目
Mid 介于做出来和完全不会之间
Hard 没思路,完全没做出来
150道刷题记录
Easy:
1.盛最多水的容器 2024.5.17
考点:双指针
class Solution {
public:
int maxArea(vector<int>& height) {
int max = 0;
int n = height.size();
for (int i = 0, j = n - 1; i < j;) {
int w = j - i;
int h = 0;
if (height[i] >= height[j]) {
h = height[j];
j--;
} else {
h = height[i];
i++;
}
if (h * w > max) {
max = h * w;
}
}
return max;
}
};
2.移动零 2024.5.20
考点:双指针,本人使用vector数组性质
class Solution {
public:
void moveZeroes(vector<int>& nums) {
int n=nums.size();
for(int j=n-1;j>=0;j--){
if(nums[j]==0){
nums.push_back(0);
nums.erase(nums.begin()+j);
}
}
}
};
3. 两数之和 2024.5.21
考点:哈希表
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
unordered_map<int, int> hashtable;
vector<int> result(2,-1);
for(int i=0;i<nums.size();i++){
hashtable[nums[i]]=i;
}
for(int i=0;i<nums.size();i++){
auto tar=hashtable.find(target-nums[i]);
if(tar!=hashtable.end()&& hashtable[target-nums[i]]!=i){
result[0]=i;
result[1]=hashtable[target-nums[i]];
}
}
return result;
}
};
4.杨辉三角 2024.5.21
搞复杂了,主要是二维vector数组表示问题
class Solution {
public:
vector<vector<int>> generate(int numRows) {
vector<vector<int>> result;
vector<int> dp(1,1);
result.push_back(dp);//[1]
if(numRows==1){
return result;
}
dp.push_back(1);
result.push_back(dp);//[1,1]
for(int i=2;i<numRows;i++){
vector<int> tem=dp;
for (int j = 1; j < i ; j++){
dp[j] = tem[j-1] + tem[j];
}
dp.push_back(1);
result.push_back(dp);
}
return result;
}
};
附上官方题解:
class Solution {
public:
vector<vector<int>> generate(int numRows) {
vector<vector<int>> ret(numRows);
for (int i = 0; i < numRows; ++i) {
ret[i].resize(i + 1);
ret[i][0] = ret[i][i] = 1;
for (int j = 1; j < i; ++j) {
ret[i][j] = ret[i - 1][j] + ret[i - 1][j - 1];
}
}
return ret;
}
};
Mid
1.三数之和 2024.5.20
暴力法三重循环做出来300/313,最后几个例子超时了,应该用一重循环+双指针,主要是排序和特殊条件判断
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
vector<vector<int>> three;
int n=nums.size();
sort(nums.begin(), nums.end()); //排序
for(int i=0;i<n-2;i++){
if(nums[i] + nums[i+1] + nums[i+2]>0){//最小三个数大于0
break;
}
if(nums[i]+nums[n-2]+nums[n-1]<0){
continue;//固定i后的最大可能性都小于0
}
if(i>0&&nums[i]==nums[i-1]){//每次枚举不同的数
continue;
}
for(int j=i+1, k=n-1;j<n-1&&j<k;j++){
int tar=-nums[i];
if(j>i+1&&nums[j]==nums[j-1]){
continue;//每次枚举不同的数
}
while(j<k&&nums[j]+nums[k]>tar){
k--;
}
if(j==k){
break;
}
if(nums[j]+nums[k]==tar){
three.push_back({nums[i],nums[j],nums[k]});
}
}
}
return three;
}
};
2.编辑距离 2024.5.20
class Solution {
public:
int minDistance(string word1, string word2) {
int l1=word1.length();
int l2=word2.length();
vector<vector<int> > arr(l1+1, vector<int>(l2+1));
if(l1==0&&l2!=0){
return l2;
}
if(l1!=0&&l2==0){
return l1;
}
if(l1==0&&l2==0){
return 0;
}
for(int i=0;i<=l1;i++){//初始化
arr[i][0]=i;
}
for(int j=0;j<=l2;j++){
arr[0][j]=j;
}
for(int i=1;i<=l1;i++){
for(int j=1;j<=l2;j++){
if(word1[i-1]==word2[j-1]){//注意是i-1和j-1
arr[i][j]=min(arr[i-1][j-1],arr[i-1][j]+1);
arr[i][j]=min(arr[i][j-1]+1,arr[i][j]);
}
else{
arr[i][j]=min(arr[i-1][j]+1,arr[i][j-1]+1);
arr[i][j]=min(arr[i-1][j-1]+1,arr[i][j]);
}
}
}
return arr[l1][l2];
}
};
3.字母异位词分组
TTL,主要是遍历循环的这两种方式并不记得了,以及没想到map的第二个元素是string数组。
class Solution {
public:
vector<vector<string>> groupAnagrams(vector<string>& strs) {
map<string, vector<string>> mp;
vector<vector<string>> res;
for (string& str: strs) {
string key = str;
sort(key.begin(), key.end());
mp[key].push_back(str);
}
for (auto it = mp.begin(); it != mp.end(); ++it) {
res.push_back(it->second);
}
return res;
}
};
Hard
1.接雨水 2024.5.17
考点:双指针
class Solution {
public:
int trap(vector<int>& height) {
//下标 i处能接的雨水量等于 min(left,right)−height[i])
int sum=0;
int left=0,right=0;//左右两侧局部最大值
for(int i=0,j=height.size()-1;i<j;){
if(height[i]>left){//用当前值更新
left=height[i];
}
if(height[j]>right){
right=height[j];
}
//右侧存在某个柱子能挡水
if(left<right){
sum=sum+left-height[i];
i++;
}
else{
sum=sum+right-height[j];
j--;
}
}
return sum;
}
};