代码随想录-LeedtCode
LeetCode704 二分查找
题目描述
给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1。
class Solution:
def search(self, nums, target):
left, right = 0, len(nums) - 1
while left <= right:
middle = (left + right) // 2
if nums[middle] < target:
left = middle + 1
elif nums[middle] > target:
right = middle - 1
else:
return middle
return -1
if __name__ == '__main__':
nums=[-1,0,3,5,9,12]
print(nums)
Solution().search(nums,9)
print(nums.index(9))
class Solution {
public static int search(int[] nums, int target) {
Arrays.sort(nums);
int low = 0;
int high = nums.length - 1;
while (low <= high) {
int middle = low + (high - low) / 2;
if (target > nums[middle]) {
low = middle + 1;
} else if (target < nums[middle]) {
high = middle - 1;
} else {
return middle;
}
}
return -1;
}
public static void main(String args[]){
int nums[]={-1,0,3,5,9,12};
int mid=(nums[0]+nums[5])/2;
int high=5;
int low=0;
int target=9;
int result=search(nums,target);
System.out.println(result);
}
}
LeetCode35 搜索插入位置
题目描述
给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。
class Solution {
public int searchInsert(int[] nums, int target) {
int low = 0;
int high = nums.length-1;
if(nums[high]<target){
return high+1;
}
if(nums[low] > target){
return 0;
}
while(low <= high){
int mid =(low+high)/2;
if (nums[mid]==target){
return mid;
}else if (nums[mid]>target){
high = mid-1;
}else {
low=mid+1;
}
}
return high+1;
}
}
class Solution:
def searchInsert(self,nums,target):
"""
:type nums: List[int]
:type target: int
:rtype: int
"""
left,right=0,len(nums)-1
if nums[0] > target:
return 0
if nums[right]<target:
return right+1
while left<=right:
mid=(left+right)//2
if nums[mid]>target:
right=mid-1
elif nums[mid]<target:
left=mid+1
else:
return mid
return right+1
if __name__ == '__main__':
nums=[1,3,5,6]
target=7
n=Solution().searchInsert(nums,target)
print(n)
LeetCode34. 在排序数组中查找元素的第一个和最后一个位置
题目描述
给定一个按照升序排列的整数数组 nums,和一个目标值 target。找出给定目标值在数组中的开始位置和结束位置。
如果数组中不存在目标值 target,返回 [-1, -1]。
class Solution {
public int[] searchRange(int nums[],int target){
int index = binarysearch(nums, target); // 二分查找
if (index == -1) { // nums 中不存在 target,直接返回 {-1, -1}
return new int[] {-1,-1};
}
// nums 中存在 targe,则左右滑动指针,来找到符合题意的区间
int left = index;
int right = index;
// 向左滑动,找左边界
while (left - 1 >= 0 && nums[left - 1] == nums[index]) { // 防止数组越界。逻辑短路,两个条件顺序不能换
left--;
}
// 向左滑动,找右边界
while (right + 1 < nums.length && nums[right + 1] == nums[index]) { // 防止数组越界。
right++;
}
return new int[] {left, right};
}
public int binarysearch(int nums[],int target){
int left=0;
int right=nums.length-1;
while (left<=right){
int mid=(left+right)/2;
if (nums[mid]>target){
right=mid-1;
}else if (nums[mid]<target){
left=mid+1;
}else {
return mid;
}
}
return -1;
}
}
class Solution:
def searchRange(self, nums: List[int], target: int) -> List[int]:
def binarySearch(nums: List[int], target: int) -> int:
left, right = 0, len(nums) - 1
while left <= right: # 不变量:左闭右闭区间
middle = left + (right - left) // 2
if nums[middle] > target:
right = middle - 1
elif nums[middle] < target:
left = middle + 1
else:
return middle
return -1
index = binarySearch(nums, target)
if index == -1: return [-1, -1] # nums 中不存在 target,直接返回 {-1, -1}
# nums 中存在 targe,则左右滑动指针,来找到符合题意的区间
left, right = index, index
# 向左滑动,找左边界
while left - 1 >= 0 and nums[left - 1] == target: left -= 1
# 向右滑动,找右边界
while right + 1 < len(nums) and nums[right + 1] == target: right += 1
return [left, right]
if __name__ == '__main__':
nums=[5,7,7,8,8,10]
target=7
n=Solution().searchRange(nums,7)
print(n)
总结
> 二分查找的两种的区间格式while(left<=right) 和 while(left<right)
前者包含left=right,right指向数组的最后一位;而后者left不等于right,right指向数组最后一位的下一位。所以不同的是mid
和mid-1
的区别
========================================================================================================
LeetCode69. x 的平方根
题目描述
由于返回类型是整数,结果只保留 整数部分 ,小数部分将被 舍去 。
注意:不允许使用任何内置指数函数和算符,例如 pow(x, 0.5) 或者 x ** 0.5 。
class Solution {
public int mySqrt(int x) {
if (x == 0) {
return 0;
}
if (x == 1) {
return 1;
}
int left=1;
int right=x/2; //x/2是关键,因为一个数的平方根不会超过自己的一半,0和1除外
while (left < right) {
int mid=left+(right-left+1)/2; //mid不加1会造成死循环
//为了避免乘法溢出,本来是mid的平方大于x,
// 如果mid的平方大于x,说明下一轮的搜索区间是[left..mid-1]
//mid就是要猜的那个数,mid的平方严格大于x的话,就要缩小查找的区间
// 所以区间是[left..mid-1]
/* try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("left = " + left + ", right = " + right + ", mid = " + mid);*/
if (mid > x / mid) {
right=mid-1;
}else {
//mid的平方大于x,说明搜索区间是[mid,right]
left=mid;
}
}
//当left=right的时候就会退出循环,所以return right也可以
return left;
}
}
class Solution(object):
def mySqrt(self, x):
"""
:type x: int
:rtype: int
"""
if x==0:
return 0
if x==1:
return 1
left,right=1,x//2
while left < right:
mid=left+(right-left+1)//2
if mid>x/mid:
right=mid-1
else:
left=mid
return left
if __name__ == '__main__':
x=8
x=Solution().mySqrt(8)
print(x)
https://leetcode-cn.com/problems/sqrtx/solution/er-fen-cha-zhao-niu-dun-fa-python-dai-ma-by-liweiw/
来源:力扣(LeetCode)
链接:https://leetcode-cn.com