算法刷題(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(231 - 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 = 1,?right = 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.pswp.cn/web/80618.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/80618.shtml
英文地址,請注明出處:http://en.pswp.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米&…