力扣二分查找
力扣二分查找
704 二分查找
1.要求
给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target ,写一个函数搜索 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]之间。
2.思路
二分查找也称为折半查找,每次都能将查找区间减半,这种折半特性的算法时间复杂度为 O(logN)
class Solution {
public int search(int[] nums, int target) {
int low=0;
int high=nums.length;
while(low<high){
int mid=low+(high-low)/2;
// System.out.println(mid);
if(nums[mid]==target){
return mid;
}else if(nums[mid]<target){
low=mid+1;
}else{
high=mid;
}
}
return -1;
}
}
69 x 的平方根
1.要求
实现 int sqrt(int x) 函数。
计算并返回 x 的平方根,其中 x 是非负整数。
由于返回类型是整数,结果只保留整数的部分,小数部分将被舍去。
示例 1:
输入: 4
输出: 2
示例 2:
输入: 8
输出: 2
说明: 8 的平方根是 2.82842…,
由于返回类型是整数,小数部分将被舍去。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/sqrtx
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
2.思路
平方的数肯定小于等于这个数的一半,然后利用2分法,寻找一个这个数;
class Solution {
public int mySqrt(int x) {
if (x <= 1) {
return x;
}
int l = 1, h = x;
while (l <= h) {
int mid = l + (h - l)/2;
int sqrt = x / mid;
if (sqrt == mid) {
return mid;
} else if (mid > sqrt) {
h = mid - 1;
} else {
l = mid + 1;
}
}
return h;
}
}
744 寻找比目标字母大的最小字母
1.要求
给定一个只包含小写字母的有序数组letters 和一个目标字母 target,寻找有序数组里面比目标字母大的最小字母。
数组里字母的顺序是循环的。举个例子,如果目标字母target = ‘z’ 并且有序数组为 letters = [‘a’, ‘b’],则答案返回 ‘a’。
示例:
输入:
letters = [“c”, “f”, “j”]
target = “a”
输出: “c”
输入:
letters = [“c”, “f”, “j”]
target = “c”
输出: “f”
输入:
letters = [“c”, “f”, “j”]
target = “d”
输出: “f”
输入:
letters = [“c”, “f”, “j”]
target = “g”
输出: “j”
输入:
letters = [“c”, “f”, “j”]
target = “j”
输出: “c”
输入:
letters = [“c”, “f”, “j”]
target = “k”
输出: “c”
注:
letters长度范围在[2, 10000]区间内。
letters 仅由小写字母组成,最少包含两个不同的字母。
目标字母target 是一个小写字母。
2.思路
因为有序,所以2分查找,寻找到一个临界点这个点,如果这个临界点到了最右边,说明全都比它小,所以取第一个字符返回,反之则取小的那个临界点(或者大的临界点+1);
class Solution {
public char nextGreatestLetter(char[] letters, char target) {
int n = letters.length;
int l = 0, h = n - 1;
while (l <= h) {
int m = l + (h - l) / 2;
if (letters[m] <= target) {
l = m + 1;
} else {
h = m - 1;
}
}
return l < n ? letters[l] : letters[0];
}
}
540有序数组中的单一元素
1.要求
给定一个只包含整数的有序数组,每个元素都会出现两次,唯有一个数只会出现一次,找出这个数。
示例 1:
输入: [1,1,2,3,3,4,4,8,8]
输出: 2
示例 2:
输入: [3,3,7,7,10,11,11]
输出: 10
注意: 您的方案应该在 O(log n)时间复杂度和 O(1)空间复杂度中运行。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/single-element-in-a-sorted-array
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
2.思路
1.暴力**两个循环;但是循环自增2,比较前后两个数是否满足;
2 2分查找,偶数位置总是一个新的数,如果,不等后一个数,证明单数一定出现在前边,反之如果相等证明证明此前的数都正常,开始找后边的数。
class Solution {
public int singleNonDuplicate(int[] nums) {
int l=0;
int h=nums.length-1;
while(l<h){
int mid=l+(h-l)/2;
if(mid%2==1){
mid--;
}
if(nums[mid]==nums[mid+1]){
l=mid+2;
}else{
h=mid;
}
}
return nums[l];
}
}
153. 寻找旋转排序数组中的最小值
1.要求
假设按照升序排序的数组在预先未知的某个点上进行了旋转。
( 例如,数组 [0,1,2,4,5,6,7] 可能变为 [4,5,6,7,0,1,2] )。
请找出其中最小的元素。
你可以假设数组中不存在重复元素。
示例 1:
输入: [3,4,5,1,2]
输出: 1
示例 2:
输入: [4,5,6,7,0,1,2]
输出: 0
2.思路
2.分查找方式
class Solution {
public int findMin(int[] nums) {
int l=0;
int h=nums.length-1;
while(l<h){
int mid=l+(h-l)/2;
if( nums[mid]<nums[h]){
h=mid;
}else{
l=mid+1;
}
}
return nums[l];
}
}
链接:https://leetcode-cn.com/problems/binary-search
https://github.com/CyC2018/CS-Notes/blob/master/notes/Leetcode%20%E9%A2%98%E8%A7%A3%20-%20%E4%BA%8C%E5%88%86%E6%9F%A5%E6%89%BE.md
上一篇: .net core