提示:写完文章后,目录可以自动生成,如何生成可参考右边的帮助文档
题目列表
【第1题】搜索旋转排序数组
LeetCode地址:https://leetcode.cn/problems/search-in-rotated-sorted-array/
1.题目描述
2.解题思路
当数组旋转后,进行二分,左边区域和右边区域一定有一个是升序的。我们可以通过比较L、M、R位置的值进行判断。当target=3时,在L-M区域是升序的,我们就可以判断target是否在这个区域里面。如果在,就对左边二分,否则对右边二分。如果左边L-M区域是无序的,那么M-R区域一定是升序的,我们通过判断target的值是否在右边区域,来决定下次是对左边还是对右边进行二分。
3.代码详解
class Solution {
public int search(int[] nums, int target) {
int L = 0;
int R = nums.length - 1;
while(L <= R){ //[]
int M = L + ((R-L) >> 1);
if(nums[M] == target){ // 先判断M位置的值是否等于target,之后再决定是否二分
return M;
}
// 三者相等,无法判断断点在左边还是右边
if(nums[L] == nums[M] && nums[M] == nums[R]){
//在左边区域一次查找不等于nums[M]的元素
while(L != M && nums[L] != nums[M]){
L++;
}
if(L == M){//到中点了还没找到不等于nums[M]的元素,二分进去下个循环
L = M + 1;
continue;
}
}
if(nums[L] != nums[M]){
if(nums[L] < nums[M]){
if(target>= nums[L] && target < nums[M]){
R = M - 1;
}else{
L = M + 1;
}
}else{
//不知道target是否在有断点的左侧,所以去有序的右侧进行判断
if(target>nums[M] && target <= nums[R]){
L = M + 1;
}else{
R = M - 1;
}
}
}else{ // nums[L] == nums[M] && nums[M] != nums[R]
if(nums[M] < nums[R]){//有序无断点
if(target > nums[M] && target <= nums[R]){
L = M + 1;
}else{
R = M - 1;
}
}else{
//不知道target是否在有断点的右侧,所以去有序的左侧进行判断
if(nums[L] <= target && target < nums[M]){
R = M - 1;
}else{
L = M + 1;
}
}
}
}
return -1;
}
}
【第2题】 在排序数组中查找元素的第一个和最后一个位置
LeetCode地址:https://leetcode.cn/problems/find-first-and-last-position-of-element-in-sorted-array/
1.题目描述
2.解题思路
先使用二分查找找到等于target的第一个数,之后依次向左向右搜索找到左右边界。
3.代码详解
class Solution {
public int[] searchRange(int[] nums, int target) {
int L = 0;
int R = nums.length - 1;
int[] res = new int[2];
while(L <= R){
int M = L + ((R - L) >> 1);
if(nums[M] == target){
int temp_l = M;
int temp_r = M;
while((temp_l - 1) >= 0 && nums[temp_l - 1] == nums[temp_l]){
temp_l--;
}
while((temp_r + 1) <= (nums.length - 1) && nums[temp_r] == nums[temp_r+1]){
temp_r++;
}
res[0] = temp_l;
res[1] = temp_r;
return res;
}else if(nums[M] < target){
L = M + 1;
}else{
R = M - 1;
}
}
res[0] = -1;
res[1] = -1;
return res;
}
}