2022.10.31
(研一学渣,打算先从数组题目开始,没事就做两道)
001 两数之和
主要错误在不熟悉C++了
解法一,暴力求解,遍历就完事了。
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
vector<int> t;
for(int i =0; i<size(nums);i++)
{
for(int j=i+1; j<size(nums); j++)
{
if(target==nums[i]+nums[j])
{
t.push_back(i);
t.push_back(j);
return t;
}
}
}
return t;
}
};
解法二,哈希表,之前数据结构学过,但忘完了。后续再补。
011装水容器
写了一个暴力求解,时间复杂度O(n^2),无语了。看了提示后才明白,双头并进,时间复杂度降到O(n)。
2022.11.01
026删除重复
这个挺顺利的,和题解的方法基本一样,和11的思想一样,双指针
class Solution {
public:
int removeDuplicates(vector<int>& nums) {
int max_p =1;
int max=nums[0];
for(int i=0;i<size(nums);i++)
{
if(nums[i]>max){
nums[max_p]=nums[i];
max=nums[i];
max_p++;
}
}
return max_p;
}
};
016最靠近的三数之和
也是暴力求解会超时,有了第11题的经验,考虑了先排序再使用双指针的办法,但还是差临门一脚,看了题解才做出来。总结,一般时间复杂度过高的话 考虑双头并进。
class Solution {
public:
int threeSumClosest(vector<int>& nums, int target) {
for (int i = 0; i < size(nums) - 1; i++)
{
for (int j = 0; j < size(nums) - i - 1; j++)
{
if (nums[j] > nums[j + 1]) { //修改这里
int temp = nums[j];
nums[j] = nums[j + 1];
nums[j + 1] = temp;
}
}
}
int sum0=nums[0]+nums[1]+nums[2];
int max=abs(target-sum0);
for(int i=0;i<size(nums)-2;i++)
{
for(int j=i+1,k=size(nums)-1;j!=k;)
{
int sum=nums[i]+nums[j]+nums[k];
if(max>abs(target-sum))
{
sum0=sum;
max =abs(target-sum);
}
if(sum<target)
j++;
if(sum>target)
k--;
if(sum==target)
return target;
}
}
return sum0;
}
};
2022.11.02
2023.02.09
一不留神2月有余,接着来吧
015三数之和
我不理解我的为什么超时,双头逼近策略
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
vector<vector<int>> re;
sort(nums.begin(), nums.end());
for(int i=0;i<nums.size()-2;i++)
{
if(i>0&&nums[i]==nums[i-1])
continue;
for(int j=i+1,k=nums.size()-1;j!=k;)
{
if(j>i+1&&nums[j]==nums[j-1])
{
j++;
continue;
}
if(k<nums.size()-1&&nums[k]==nums[k+1])
{
k--;
continue;
}
int sum=nums[k]+nums[j];
if(sum == -nums[i])
{
re.push_back({nums[1],nums[j],nums[k]});
}
if(sum> -nums[i])
k--;
if(sum< -nums[i])
j++;
}
}
return re;
}
};
033 搜索旋转排序数组
第一道二分法题目,要求时间复杂度o(logn)肯定是二分法,如何判断在哪一段是关键;
“
将数组一分为二,其中一定有一个是有序的,另一个可能是有序,也能是部分有序。
此时有序部分用二分法查找。无序部分再一分为二,其中一个一定有序,另一个可能有序,可能无序。就这样循环.
”
class Solution {
public:
int search(vector<int>& nums, int target) {
int n=nums.size();
int l=0;
int r=n-1;
for(;l<=r;)
{
int mid=(l+r)/2;
if(target==nums[mid])
return mid;
if(nums[mid]>=nums[l])
{
if(target>=nums[l]&&target<nums[mid])
r=mid-1;
else
l=mid+1;
}
else
{
if(target>nums[mid]&&target<=nums[r])
l=mid+1;
else
r=mid-1;
}
}
return -1;
}
};
035 搜索插入位置
就很简单,但我写复杂了。贴个官方答案吧。
另,二分法中可能出现(left+right)/2超限的问题,可使用 left+(right-left)/2代替
class Solution {
public:
int searchInsert(vector<int>& nums, int target) {
int n = nums.size();
int left = 0, right = n - 1, ans = n;
while (left <= right) {
int mid = ((right - left) >> 1) + left;
if (target <= nums[mid]) {
ans = mid;
right = mid - 1;
} else {
left = mid + 1;
}
}
return ans;
}
};
2023.02.10
018四数之和
如出一辙,注意一些剪枝操作
代码不贴了,sb题目。
034排序数组查找元素
有一个二分法的题目,主要是找左边界和右边界,回头整一个二分法的合集。
class Solution {
public:
vector<int> searchRange(vector<int>& nums, int target) {
int n=nums.size();
vector<int> ans;
int rb=-2;
int lb=-2;
//找左边界
for(int l=0,r=n-1;l<=r;)
{
int mid = l+(r-l)/2;
if(nums[mid]>=target)
{
r=mid-1;
lb=r;
}
else
l=mid+1;
}
for(int l=0,r=n-1;l<=r;)
{
int mid = l+(r-l)/2;
if(nums[mid]<=target)
{
l=mid+1;
rb=l;
}
else
r=mid-1;
}
if(rb == -2||lb == -2){return {-1,-1};}
if(rb-lb>1)
{return {lb+1,rb-1};}
return {-1,-1};
}
};
2023.02.11
036 有效的数独
第一次尝试使用哈希表,不太习惯。题解的方法明显更好,但还是贴我的吧。
class Solution {
public:
bool isValidSudoku(vector<vector<char>>& board) {
for(int i=0;i<9;i++)
{
unordered_map<int, int> m;
for(int j=0;j<9;j++)
{
if(board[i][j]=='.')
continue;
if(!m.count(board[i][j]))
m.insert(pair<int,int>(board[i][j],j));
else
return false;
}
}
for(int i=0;i<9;i++)
{
unordered_map<int, int> m;
for(int j=0;j<9;j++)
{
if(board[j][i]=='.')
continue;
if(!m.count(board[j][i]))
m.insert(pair<int,int>(i,board[j][i]));
else
return false;
}
}
for(int i=0;i<9;i=i+3)
{
for(int j=0;j<9;j=j+3)
{
unordered_map<int, int> ma;
for(int m=i;m<i+3;m++)
{
for(int k=j;k<j+3;k++)
{
if(board[m][k]=='.')
continue;
if(!ma.count(board[m][k]))
{
ma.insert(pair<int,int>(board[m][k],m));
}
else
return false;
}
}
}
}
return true;
}
};