leetcode中的二分查找
二分查找
给定一个个元素有序的(升序)整型数组和一个目标值,写一个函数搜索$nums 中的 target,如果目标值存在返回下标,否则返回 -1。
示例 1:
输入: nums = [-1,0,3,5,9,12], target = 9
输出: 4
解释: 9 出现在 nums 中并且下标为 4
示例 2:
输入: nums = [-1,0,3,5,9,12], target = 2
输出: -1
解释: 2 不存在 nums 中因此返回 -1
提示:
你可以假设 nums 中的所有元素是不重复的。
n 将在 [1, 10000]之间。
nums 的每个元素都将在 [-9999, 9999]之间。
class Solution {
public:
int search(vector<int>& nums, int target) {
int n=nums.size();
int l=0,r=n-1;
int ans=0;
while(r>=l){
int mid=(l+r)/2;
if(nums[mid]<=target){
ans=mid;
l=mid+1;
}
else{
r=mid-1;
}
}
if(ans==-1||nums[ans]!=target){
return -1;
}
return ans;
}
};
给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。
请必须使用时间复杂度为的算法。
示例 1:
输入: nums = [1,3,5,6], target = 5
输出: 2
示例 2:
输入: nums = [1,3,5,6], target = 2
输出: 1
示例 3:
输入: nums = [1,3,5,6], target = 7
输出: 4
提示:
nums 为 无重复元素 的 升序 排列数组
class Solution {
public:
int searchInsert(vector<int>& nums, int target) {
if(nums[0]>=target){
return 0;
}
int l=0,r=nums.size()-1,ans=0;
while(r>=l){
int mid=(l+r)/2;
if(nums[mid]<target){
ans=mid;
l=mid+1;
}
else{
r=mid-1;
}
}
return ans+1;
}
};
int searchInsert(int* nums, int numsSize, int target){
int left=0,right=numsSize-1;
while(left<=right){
int mid=(left+right)/2;
if(nums[mid]==target)
return mid;
else if(nums[mid]>target)
right=mid-1;
else if(nums[mid]<target)
left=mid+1;
}
return left;
}
寻找比目标字母大的最小字母
给你一个字符数组,该数组按非递减顺序排序,以及一个字符,里至少有两个不同的字符。
返回中大于的最小的字符。如果不存在这样的字符,则返回的第一个字符。
示例 1:
输入: letters = ["c", "f", "j"],target = "a"
输出: "c"
解释:letters 中字典上比 'a' 大的最小字符是 'c'。
示例 2:
输入: letters = ["c","f","j"], target = "c"
输出: "f"
解释:letters 中字典顺序上大于 'c' 的最小字符是 'f'。
示例 3:
输入: letters = ["x","x","y","y"], target = "z"
输出: "x"
解释:letters 中没有一个字符在字典上大于 'z',所以我们返回 letters[0]。
提示:
letters[i] 是一个小写字母
letters 按非递减顺序排序
letters 最少包含两个不同的字母
target 是一个小写字母
class Solution {
public:
char nextGreatestLetter(vector<char>& letters, char target) {
int l=0,r=letters.size()-1,ans=0;
while(r>=l){
int mid=(l+r)/2;
if(letters[mid]>target){
r=mid-1;
ans=mid;
}
else{
l=mid+1;
}
}
return letters[ans];
}
};
统计有序矩阵中的负数
给你一个的矩阵,矩阵中的元素无论是按行还是按列,都以非递增顺序排列。 请你统计并返回中 负数 的数目。
示例 1:
输入:grid = [[4,3,2,-1],[3,2,1,-1],[1,1,-1,-2],[-1,-1,-2,-3]]
输出:8
解释:矩阵中共有 8 个负数。
示例 2:
输入:grid = [[3,2],[1,0]]
输出:0
提示:
m == grid.length
n == grid[i].length
1 <= m, n <= 100
-100 <= grid[i][j] <= 100
class Solution {
public:
int countNegatives(vector<vector<int>>& grid) {
int ans=0;
int n=grid.size();
int m=grid[0].size();
for(int i=0;i<n;i++){
int l=0,r=m-1,res=m;
while(r>=l){
int mid=(l+r)/2;
if(grid[i][mid]<0){
r=mid-1;
res=mid;
}
else{
l=mid+1;
}
}
ans+=abs(m-res);
}
return ans;
}
};
寻找右区间
给你一个区间数组,其中,且每个都 不同 。
区间的 右侧区间 可以记作区间,并满足,且最小化 。注意可能等于。
返回一个由每个区间的右侧区间在中对应下标组成的数组。如果某个区间不存在对应的 右侧区间 ,则下标处的值设为。
示例 1:
输入:intervals = [[1,2]]
输出:[-1]
解释:集合中只有一个区间,所以输出-1。
示例 2:
输入:intervals = [[3,4],[2,3],[1,2]]
输出:[-1,0,1]
解释:对于 [3,4] ,没有满足条件的“右侧”区间。
对于 [2,3] ,区间[3,4]具有最小的“右”起点;
对于 [1,2] ,区间[2,3]具有最小的“右”起点。
示例 3:
输入:intervals = [[1,4],[2,3],[3,4]]
输出:[-1,2,-1]
解释:对于区间 [1,4] 和 [3,4] ,没有满足条件的“右侧”区间。
对于 [2,3] ,区间 [3,4] 有最小的“右”起点。
提示:
intervals[i].length == 2
每个间隔的起点都 不相同
这个题就是按照,排序之后然后再按照二分查找就行
class Solution {
public:
vector<int> findRightInterval(vector<vector<int>>& intervals) {
vector<int>ans;
vector<vector<int>> a=intervals;
int n=intervals.size();
map<int,int>mp;
for(int i=0;i<n;i++){
mp[intervals[i][0]]=i;
}
sort(a.begin(),a.end());
for(int i=0;i<n;i++){
// cout<<a[i][0]<<" "<<a[i][1]<<endl;
int l=0,r=n-1,res=-1;
while(r>=l){//1 3 4 5
int mid=(l+r)/2;
if(a[mid][0]>=a[i][1]){
r=mid-1;
res=mid;
}
else{
l=mid+1;
}
}
ans.push_back(res);
}
vector<int>v(n);
for(int i=0;i<n;i++){
if(ans[i]==-1){
v[mp[a[i][0]]]=-1;
}
else{
v[mp[a[i][0]]]=mp[a[ans[i]][0]];
}
}
return v;
}
};
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 终于写完轮子一部分:tcp代理 了,记录一下
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
2020-11-11 素数阶乘取余—(威尔逊定理)
2020-11-11 快速乘法+快速幂
2020-11-11 线段树维护连续区间