算法刷题(Java与Python)1.二分查找

目录

二分查找

思路

总体

细节

问题一,为什么循环的条件是left<=right   ,为什么要有等号呢

问题二,为什么中间值是left +(right - left) / 2

问题三,为什么最后返回的是左边的值呢

情况 1:target 存在于数组中

情况 2:target 不存在于数组中

例题1

代码实现

Java

Python 

例题2

Java

Python

例题三

Java

Python

总结


二分查找

思路

总体

二分查找前提是已经是从小到大排序了,就是对半着查找

一开始先看最中间那个

如果等于,那就找到了,直接返回

如果目标小于中间值,那么把右边界赋值为中间值减一

如果目标大于中间值,那么把左边界赋值为中间值加一

细节

问题一,为什么循环的条件是left<=right   ,为什么要有等号呢
  • 当 left == right 时,搜索区间仍然包含 一个元素(即 nums[left] 或 nums[right]),需要检查这个元素是否等于 target

问题二,为什么中间值是left +(right - left) / 2

(right - left)只是偏移量,在0~5是可以用的, 但是如果最左边不是0,那就错了,要加上最左边

一开始写的是(left +right)/2    但是这样有可能会溢出  ,超出java  int类型的最大值,导致结果是负数,  java  int最大值是2,147,483,647(2³¹ - 1)     ,java的第一位是符号位,如果你超出了最大值,就会变成负数,负数除2还是负数。

int max = Integer.MAX_VALUE; // 2147483647 (0x7FFFFFFF)
int overflow = max + 1;      // 溢出后变为 -2147483648 (0x80000000)

注意:

>>是有符号右移 / 算术右移     ,移了之后原符号不变

>>>(无符号右移 / 逻辑右移), ,移了之后原符号可能改变

可以采用

方法一:left +(right - left) / 2

方法二:(left +right)>>>1,是向下取整的

虽然说超出了是负数,但其实二进制的数还是一样的,只是java把第一位看作是符号位,所以你向右移一位,其实就是除二向下取整

问题三,为什么最后返回的是左边的值呢
情况 1:target 存在于数组中
  • 在循环中直接返回 mid,不会走到最后的 return 语句。

情况 2:target 不存在于数组中
  • left 的物理意义

    • 它是 target 应该插入的位置,即第一个比 target 大的元素的位置。

    • 如果所有元素都比 target 小,left 会停在 len(nums)(数组末尾之后)。

    • 如果所有元素都比 target 大,left 会停在 0(数组开头)。

  • right 的问题

    • right 指向的是最后一个比 target 小的元素,插入后会破坏顺序。

    • 例如 nums = [1,3,5,6]target = 2

      • 终止时 left = 1right = 0

      • 插入到 left(1)是正确的 [1, **2**, 3, 5, 6],而 right(0)会错误地插入到开头。

例题1

代码实现

Java
package Test;import java.util.HashMap;
import java.util.Map;class Solution {public static int searchInsert(int[] nums, int target) {int length = nums.length;int left = 0;int right = length - 1;while (left <= right) {int mid = left +(right - left) / 2;//为什么是这样呢,(right - left)只是偏移量,在0~5是可以用的// 但是如果最左边不是0,那就错了,要加上最左边if (nums[mid] == target) {return mid;}else if(target<nums[mid]){right = mid - 1;}else if (target>nums[mid]) {left = mid + 1;}}return left;}public  static void main(String[] args) {int[] nums = {1,3,5,6};System.out.println(searchInsert(nums, 2));for (int num : nums) {System.out.print(num);}}
}

Python 

注意python中,/是有小数点的除   // 是整除,向下取整


class Solution:def searchInsert( self,nums, target):length = len(nums)left = 0right = length - 1while left<=right:mid=left+(right-left)//2if target==nums[mid]:return midif target<nums[mid]:right=mid-1if target>nums[mid]:left=mid+1return left;
solution = Solution()
nums=[1,3,5,6]
print(solution.searchInsert(nums, 2))  # 输出: 1

例题2

Java

class Solution {public int search(int[] nums, int target) {int length = nums.length;int left = 0;int right = length - 1;while (left <= right) {int mid = left +(right - left) / 2;//为什么是这样呢,(right - left)只是偏移量,在0~5是可以用的// 但是如果最左边不是0,那就错了,要加上最左边if (nums[mid] == target) {return mid;}else if(target<nums[mid]){right = mid - 1;}else if (target>nums[mid]) {left = mid + 1;}}return -1;}
}

Python

class Solution(object):def search(self, nums, target):mid=-1left=0right=len(nums)-1while left<=right:mid=left+(right-left)//2if(nums[mid]==target):return midelif(target<nums[mid]):right=mid-1else:left=mid+1return -1

例题三

Java

在这次写法中,使用二分法之前,我先判断了数组是不是为空,和目标值在不在范围里面,可以避免无效的搜索,是一个优化的方法

package Test;import java.util.HashMap;
import java.util.Map;class Solution {public static int[] searchInsert(int[] nums, int target) {int length = nums.length;int left = 0;int right = length - 1;int leftcadidate=-1;int rightcadidate=-1;int[]result={leftcadidate,rightcadidate};//情况1,数组为空if(length==0)return result;//情况2,目标值超出范围// 我们知道了这个数组是递增的,那么我们先取边界值和目标值比较,如果不再范围内直接就返回了if(target<nums[0]||target>nums[length-1])return result;//情况三:目标值在范围里面while (left <= right) {int mid = left +(right - left) / 2;if (nums[mid] == target) {leftcadidate = mid;right = mid - 1;}else if(target<nums[mid]){right = mid - 1;}else if (target>nums[mid]) {left = mid + 1;}}left = 0;right = length - 1;while (left <= right) {int mid = left +(right - left) / 2;if (nums[mid] == target) {rightcadidate=mid;left = mid + 1;}else if(target<nums[mid]){right = mid - 1;}else if (target>nums[mid]) {left = mid + 1;}}result[0]=leftcadidate;result[1]=rightcadidate;return result;}public  static void main(String[] args) {int[] nums = {5,7,7,8,8,10};int target = 6;int [] result=searchInsert(nums, target);for (int i = 0; i < result.length; i++) {System.out.println(result[i]);}}
}

Python

class Solution(object):def searchRange(self, nums, target):mid=-1left=0right=len(nums)-1leftcandidate=-1while left<=right:mid=left+(right-left)//2if(target<nums[mid]):right=mid-1elif(nums[mid]<target):left=mid+1else:right=mid-1leftcandidate=midmid = -1left = 0right = len(nums)-1rightcandidate = -1while left <= right:mid = left + (right - left) // 2if (target < nums[mid]):right = mid - 1elif (nums[mid] < target):left = mid + 1else:left=mid+1rightcandidate = midreturn [leftcandidate,rightcandidate]

总结

1.数组的长度是length,但是数组是从零开始,使用数组的最后一个数字下标是length-1

2.可以先判断边界值和数组是否为空来优化算法

3.java创建数组是    int nums[]={1,2,3,4,5};

python是   nums=[1,2,3,4,5]

4.数组有可能为空,调用nums.length 会抛出异常,所以最开始要先判断是否为空(为空和数组长度为0是不一样的)(我的代码没有加入这个)。

在python,可以使用

if nums is None:return [-1,-1]

来判断是否为空

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/80618.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

芯片生态链深度解析(二):基础设备篇——人类精密制造的“巅峰对决”

【开篇&#xff1a;设备——芯片工业的“剑与盾”】 当ASML的EUV光刻机以每秒5万次激光脉冲在硅片上雕刻出0.13nm精度的电路&#xff08;相当于在月球表面精准定位一枚二维码&#xff09;&#xff0c;当国产28nm光刻机在华虹产线实现“从0到1”的突破&#xff0c;这场精密制造…

MongoTemplate 基础使用帮助手册

前言 MongoDB 是一种流行的 NoSQL 数据库&#xff0c;适合存储大量的非结构化数据。MongoTemplate 是 Spring Data MongoDB 中的一个核心组件&#xff0c;它提供了一组丰富的 API 来与 MongoDB 进行交互。它封装了许多常见的数据库操作&#xff0c;使开发者能够轻松执行 CRUD 操…

psotgresql18 源码编译安装

环境&#xff1a; 系统&#xff1a;centos7.9 数据库&#xff1a;postgresql18beta1 #PostgreSQL 18 已转向 DocBook XML 构建体系&#xff08;SGML 未来将被弃用&#xff09;。需要安装 XML 工具链&#xff0c;如下&#xff1a; yum install -y docbook5-style-xsl libxsl…

C++编程起步项目

员工信息管理系统 需求 Employee.h #pragma once#include<iostream> #include<string>using namespace std;class Employee { public:int id; // 编号string name; // 姓名string position; // 岗位int deptId; // 部门编号Employee();Employee(int id, string n…

Linux的MySQL头文件和找不到头文件问题解决

头文件 #include <iostream> #include <mysql_driver.h> #include <mysql_connection.h> #include <cppconn/statement.h> #include <cppconn/resultset.h> #include <cppconn/prepared_statement.h> #include <cppconn/exception.h&g…

[ linux-系统 ] 命令行参数 | 环境变量

命令行参数 命令行参数是指用户在启动程序时通过命令行传递给程序的参数。这些参数可以用于控制程序的行为、传递输入数据或配置选项。 在 C/C 中&#xff0c;命令行参数通过 main 函数的参数传递 命令行参数列表 argc:参数的个数 argv[]&#xff1a;参数的清单 为什么要…

新书速览|鸿蒙HarmonyOS NEXT开发之路 卷2:从入门到应用篇

《鸿蒙HarmonyOS NEXT开发之路 卷2&#xff1a;从入门到应用篇》 01 本书内容 《鸿蒙HarmonyOS NEXT开发之路 卷2&#xff1a;从入门到应用篇》是一本深度聚焦HarmonyOS NEXT应用开发的全方位指导书&#xff0c;内容遵循由浅入深的原则展开。全书分为基础知识、应用开发进阶和…

经典密码学和现代密码学的结构及其主要区别(1)凯撒密码——附py代码

密码学是一门通过使用代码和密码来保护信息的艺术与科学&#xff0c;其历史可以追溯到数千年前。古典密码学代表了这一古老学科早期的篇章。早在计算机和现代加密算法出现之前&#xff0c;历史上的各个文明就依靠巧妙的方法来保护机密、安全通信以及获取战略优势。 古典密码学…

Python60日基础学习打卡D30

回顾&#xff1a; 导入官方库的三种手段导入自定义库/模块的方式导入库/模块的核心逻辑&#xff1a;找到根目录&#xff08;python解释器的目录和终端的目录不一致&#xff09; # 直接导入 from random import randint print(randint(1, 10)) # 导入自定义库 import module m…

Linux利用多线程和线程同步实现一个简单的聊天服务器

1. 概述 本文实现一个基于TCP/IP的简单多人聊天室程序。它包含一个服务器端和一个客户端&#xff1a;服务器能够接收多个客户端的连接&#xff0c;并将任何一个客户端发来的消息广播给所有其他连接的客户端&#xff1b;客户端则可以连接到服务器&#xff0c;发送消息并接收来自…

ubuntu系统 | dify+ollama+deepseek搭建本地应用

1、安装 Ollama 下载并安装 Ollama (llm) wangqiangwangqiang:~$ curl -fsSL https://ollama.ai/install.sh | bash >>> Installing ollama to /usr/local >>> Downloading Linux amd64 bundle0.3% curl -fsSL https://ollama.ai/install.sh &#xff08;下…

从纸质契约到智能契约:AI如何改写信任规则与商业效率?​——从智能合约到监管科技,一场颠覆传统商业逻辑的技术革命

一、传统合同的“低效困境”&#xff1a;耗时、昂贵、风险失控 近年来&#xff0c;全球商业环境加速向数字化转型&#xff0c;但合同管理却成为企业效率的“阿喀琉斯之踵”。据国际商会&#xff08;International Chamber of Commerce&#xff09;数据显示&#xff0c;全球企业…

【机器学习|学习笔记】基于生成对抗网络的孪生框架(GAN-based Siamese framework,GSF)详解,附代码。

【机器学习|学习笔记】基于生成对抗网络的孪生框架(GAN-based Siamese framework,GSF)详解,附代码。 【机器学习|学习笔记】基于生成对抗网络的孪生框架(GAN-based Siamese framework,GSF)详解,附代码。 文章目录 【机器学习|学习笔记】基于生成对抗网络的孪生框架(G…

UEFI Spec 学习笔记---33 - Human Interface Infrastructure Overview---33.2.6 Strings

33.2.6 Strings UEFI 环境中的 string 是使用 UCS-2 格式定义&#xff0c;每个字符由 16bit 数据表示。对于用户界面&#xff0c;strings 也是一种可以安装到 HIIdatabase 的一种数据。 为了本土化&#xff0c;每个 string 通过一个唯一标识符来识别&#xff0c;而每一个标识…

Stable Diffusion 学习笔记02

模型下载网站&#xff1a; 1&#xff0c;LiblibAI-哩布哩布AI - 中国领先的AI创作平台 2&#xff0c;Civitai: The Home of Open-Source Generative AI 模型的安装&#xff1a; 将下载的sd模型放置在sd1.5的文件内即可&#xff0c;重启客户端可用。 外挂VAE模型&#xff1a…

并发编程(5)

抛异常时会释放锁。 当线程在 synchronized 块内部抛出异常时&#xff0c;会自动释放对象锁。 public class ExceptionUnlockDemo {private static final Object lock new Object();public static void main(String[] args) {Thread t1 new Thread(() -> {synchronized …

贵州某建筑物挡墙自动化监测

1. 项目简介 某建筑物位于贵州省某县城区内&#xff0c;靠近县城主干道&#xff0c;周边配套学校、医院、商贸城。建筑物临近凤凰湖、芙蓉江等水系&#xff0c;主打“湖景生态宜居”。改建筑物总占地面积&#xff1a;约5.3万平方米&#xff1b;总建筑面积&#xff1a;约15万平…

6个月Python学习计划:从入门到AI实战(前端开发者进阶指南)

作者&#xff1a;一名前端开发者的进阶日志 计划时长&#xff1a;6个月 每日学习时间&#xff1a;2小时 覆盖方向&#xff1a;Python基础、爬虫开发、数据分析、后端开发、人工智能、深度学习 &#x1f4cc; 目录 学习目标总览每日时间分配建议第1月&#xff1a;Python基础与编…

【FAQ】HarmonyOS SDK 闭源开放能力 —Vision Kit (3)

1.问题描述&#xff1a; 通过CardRecognition识别身份证拍照拿到的照片地址&#xff0c;使用该方法获取不到图片文件&#xff0c;请问如何解决&#xff1f; 解决方案&#xff1a; //卡证识别实现页&#xff0c;文件名为CardDemoPage&#xff0c;需被引入至入口页 import { …

AI全域智能监控系统重构商业清洁管理范式——从被动响应到主动预防的监控效能革命

一、四维立体监控网络技术架构 1. 人员行为监控 - 融合人脸识别、骨骼追踪与RFID工牌技术&#xff0c;身份识别准确率99.97% - 支持15米超距夜间红外监控&#xff08;精度0.01lux&#xff09; 2. 作业过程监控 - UWB厘米级定位技术&#xff08;误差&#xff1c;0.3米&…