35.搜索插入位置
题目链接:35. 搜索插入位置 - 力扣(LeetCode)
解题思路:
二分法,注意左闭右开/左闭右闭
class Solution {
public:
int searchInsert(vector<int>& nums, int target)
{
int left=0,right=nums.size()-1;
while(left<=right)
{
int mid=left+(right-left)/2;
if(nums[mid]>target)
{
right=mid-1;
}
else if(nums[mid]<target)
left=mid+1;
else
return mid;
}
return right+1;
}
};
34. 在排序数组中查找元素的第一个和最后一个位置
class Solution {
// lower_bound 返回最小的满足 nums[i] >= target 的 i
// 如果数组为空,或者所有数都 < target,则返回 nums.size()
// 要求 nums 是非递减的,即 nums[i] <= nums[i + 1]
// 闭区间写法
int lower_bound(vector<int> &nums, int target) {
int left = 0, right = (int) nums.size() - 1; // 闭区间 [left, right]
while (left <= right) { // 区间不为空
// 循环不变量:
// nums[left-1] < target
// nums[right+1] >= target
int mid = left + (right - left) / 2;
if (nums[mid] < target)
left = mid + 1; // 范围缩小到 [mid+1, right]
else
right = mid - 1; // 范围缩小到 [left, mid-1]
}
return left; // 或者 right+1
}
// 左闭右开区间写法
int lower_bound2(vector<int> &nums, int target) {
int left = 0, right = nums.size(); // 左闭右开区间 [left, right)
while (left < right) { // 区间不为空
// 循环不变量:
// nums[left-1] < target
// nums[right] >= target
int mid = left + (right - left) / 2;
if (nums[mid] < target)
left = mid + 1; // 范围缩小到 [mid+1, right)
else
right = mid; // 范围缩小到 [left, mid)
}
return left; // 或者 right
}
// 开区间写法
int lower_bound3(vector<int> &nums, int target) {
int left = -1, right = nums.size(); // 开区间 (left, right)
while (left + 1 < right) { // 区间不为空
// 循环不变量:
// nums[left] < target
// nums[right] >= target
int mid = left + (right - left) / 2;
if (nums[mid] < target)
left = mid; // 范围缩小到 (mid, right)
else
right = mid; // 范围缩小到 (left, mid)
}
return right; // 或者 left+1
}
public:
vector<int> searchRange(vector<int> &nums, int target) {
int start = lower_bound(nums, target); // 使用其中一种写法即可
if (start == nums.size() || nums[start] != target)
return {-1, -1};
// 如果 start 存在,那么 end 必定存在
int end = lower_bound(nums, target + 1) - 1;
return {start, end};
}
};
- 69.x 的平方根
class Solution {
public:
int mySqrt(int x)
{
int left=0,right=x,ans=-1;
while(left<=right)
{
int mid=left+(right-left)/2;
if((long long)mid*mid<=x)
{
ans=mid;
left=mid+1;
}
else
{
right=mid-1;
}
}
return ans;
}
};
367.
一个套路简单的
class Solution {
public:
bool isPerfectSquare(int num)
{
int left=1,right=num;
while(left<=right)
{
int mid=left+(right-left)/2;
if((long long)mid*mid<num)
{
left=mid+1;
}
else if((long long)mid*mid>num)
right=mid-1;
else
return true;
}
return false;
}
};
26. 删除有序数组中的重复项
class Solution {
public:
int removeDuplicates(vector<int>& nums)
{
int slow=0;
for(int fast=1;fast<nums.size();fast++)
{
if(nums[slow]!=nums[fast])
{
nums[slow+1]=nums[fast];//注意赋值
slow++;
}
}
return slow+1;
}
};
class Solution {
public:
void moveZeroes(vector<int>& nums)
{
int slow=0,fast=0;
while(fast<nums.size())
{
if(nums[fast])
{
swap(nums[slow],nums[fast]);
slow++;
}
fast++;
}
}
};
class Solution {
public:
bool backspaceCompare(string S, string T) {
int i = S.length() - 1, j = T.length() - 1;
int skipS = 0, skipT = 0;
while (i >= 0 || j >= 0) {
while (i >= 0) {
if (S[i] == '#') {
skipS++, i--;
} else if (skipS > 0) {
skipS--, i--;
} else {
break;
}
}
while (j >= 0) {
if (T[j] == '#') {
skipT++, j--;
} else if (skipT > 0) {
skipT--, j--;
} else {
break;
}
}
if (i >= 0 && j >= 0) {
if (S[i] != T[j]) {
return false;
}
} else {
if (i >= 0 || j >= 0) {
return false;
}
}
i--, j--;
}
return true;
}
};
- 977.有序数组的平方
class Solution {
public:
vector<int> sortedSquares(vector<int>& nums)
{
vector<int>res(nums.size(),0);
int left=0,right=nums.size()-1;
int k=nums.size()-1;
while(left<=right)
{
if(nums[right]*nums[right]<nums[left]*nums[left])
{
res[k--]=nums[left]*nums[left];
left++;
}
else
{
res[k--]=nums[right]*nums[right];
right--;
}
}
return res;
}
};
class Solution {
public:
int totalFruit(vector<int>& fruits)
{
unordered_map<int,int>mp;
int n=fruits.size();
int left=0,ans=0;
for(int right=0;right<n;right++)
{
mp[fruits[right]]++;
while(mp.size()>2)
{
auto it=mp.find(fruits[left]);
--it->second;
if(it->second==0)
{
mp.erase(it);
}
++left;
}
ans=max(ans,right-left+1);
}
return ans;
}
};
class Solution {
public:
unordered_map<char,int>ori;
unordered_map<char,int>cnt;
bool check()
{
for(const auto&p:ori)
{
if(cnt[p.first]<p.second)
return false;
}
return true;
}
string minWindow(string s, string t)
{
//记录t中各个元素的个数
for(const auto &c:t)
{
++ori[c];
}
int l=0,r=-1;
int len=INT_MAX,ansl=-1,ansr=-1;
while(r<int(s.size()))
{
//s右边界的元素在t中存在,就在s的计数中加
if(ori.find(s[++r])!=ori.end())
{
++cnt[s[r]];
}
//当所有的t中元素都存在于当前s中
while(check()&&l<=r)
{
if(r-l+1<len)
{
len=r-l+1;
ansl=l;
}
if(ori.find(s[l])!=ori.end())
{
--cnt[s[l]];
}
++l;
}
}
return ansl==-1?string():s.substr(ansl,len);
}
};
54. 螺旋矩阵
和59题区分开++up还是up--
如果是先++应该是>
up--应该>=
class Solution {
public:
vector<int> spiralOrder(vector<vector<int>>& matrix)
{
vector<int>res;
if(matrix.empty())
return res;
int left=0,right=matrix[0].size()-1,up=0,down=matrix.size()-1;
while(true)
{
for(int i=left;i<=right;++i)
{
res.push_back(matrix[up][i]);
}
if(++up>down)
break;
for(int i=up;i<=down;++i)
{
res.push_back(matrix[i][right]);
}
if(--right<left)
break;
for(int i=right;i>=left;--i)
{
res.push_back(matrix[down][i]);
}
if(--down<up)
break;
for(int i=down;i>=up;--i)
{
res.push_back(matrix[i][left]);
}
if(++left>right)
break;
}
return res;
}
};
面试29.顺时针打印矩阵
同59和54,一样的题