【Leetcode】top 100 二分查找

35 搜索插入位置

给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。请必须使用时间复杂度为 O(log n) 的算法。

基础写法!!!牢记!!!

第一个只适用与一个目标值的情况,第二个适用于多个目标值靠左取的情况(要靠右取可以找target+1获得下标值-1);

class Solution(object):
    def searchInsert(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: int
        """
        left, right = 0, len(nums)-1
        while left <= right:
            mid = (left+right)//2
            if target == nums[mid]:return mid
            elif target < nums[mid]:
                right = mid-1
            else:
                left = mid+1
        return left

def lower_bound(nums, target):
    left, right = 0, len(nums) - 1  # 闭区间 [left, right]
    while left <= right: 
        mid = (left + right) // 2
        if nums[mid] < target:
            left = mid + 1         # 范围缩小到 [mid+1, right]
        else:
            right = mid - 1        # 范围缩小到 [left, mid-1]
    return left
 74 搜索二维矩阵

给你一个满足下述两条属性的 m x n 整数矩阵:

  • 每行中的整数从左到右按非严格递增顺序排列。
  • 每行的第一个整数大于前一行的最后一个整数。

给你一个整数 target ,如果 target 在矩阵中,返回 true ;否则,返回 false 。

方法一:二分先找列再找行    定列的时候要靠近小值(取down)

              或者将二维矩阵拉成一维矩阵然后同题35      时间复杂度相同O(logm+logn)

class Solution(object):
    def searchMatrix(self, matrix, target):
        """
        :type matrix: List[List[int]]
        :type target: int
        :rtype: bool
        """
        up, down = 0, len(matrix)-1
        while up <= down:
            mid = (up+down)//2
            if target == matrix[mid][0]: return True
            elif target < matrix[mid][0]:
                down = mid-1
            else:
                up = mid+1
        
        left, right = 0, len(matrix[0])-1
        while left <= right:
            mid = (left+right)//2
            if target == matrix[down][mid]: return True
            elif target < matrix[down][mid]:
                right = mid-1
            else:
                left = mid+1
        return False

方法二:满足题目规定的二维矩阵可以看成一棵二叉搜索树    时间复杂度O(m+n)

class Solution:
    def searchMatrix(self, matrix, target):
        m, n = len(matrix), len(matrix[0])
        x, y = 0, n - 1
        while x < m and y >= 0:
            if matrix[x][y] > target:
                y -= 1
            elif matrix[x][y] < target:
                x += 1
            else:
                return True
        return False
34 在排序数组中查找元素的第一个和最后一个位置

给你一个按照非递减顺序排列的整数数组 nums,和一个目标值 target。请你找出给定目标值在数组中的开始位置和结束位置。如果数组中不存在目标值 target,返回 [-1, -1]。你必须设计并实现时间复杂度为 O(log n) 的算法解决此问题。

两遍二分查找,第一遍找target,第二遍找target+1,都靠左取;

不存在目标值情况:目标值过小/大,idx1=0/len(nums)

                                 目标值没出现:nums[idx1] != target    (可以和idx1=0合并)

class Solution(object):
    def searchRange(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: List[int]
        """
        left, right = 0, len(nums)-1
        while left <= right:
            mid = (left+right)//2
            if nums[mid] < target:
                left = mid+1
            else:
                right = mid-1
        idx1 = left

        left, right = 0, len(nums)-1
        while left <= right:
            mid = (left+right)//2
            if nums[mid] < target+1:
                left = mid+1
            else:
                right = mid-1
        idx2 = left-1

        if idx1 == len(nums) or nums[idx1] != target: return [-1, -1]
        else: return [idx1, idx2]
33 搜索旋转排列数组

整数数组 nums 按升序排列,数组中的值 互不相同 。在传递给函数之前,nums 在预先未知的某个下标 k0 <= k < nums.length)上进行了 旋转,使数组变为 [nums[k], nums[k+1], ..., nums[n-1], nums[0], nums[1], ..., nums[k-1]](下标 从 0 开始 计数)。给你 旋转后 的数组 nums 和一个整数 target ,如果 nums 中存在这个目标值 target ,则返回它的下标,否则返回 -1 。你必须设计一个时间复杂度为 O(log n) 的算法解决此问题。

二分出一侧排序正确的区域,若target在这个区域里,正常查找,若在排序不正确的区域里,继续二分;

因为目标值仅出现一次,可提前判断;

找不到递增区间时终止循环;

class Solution(object):
    def search(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: int
        """
        left, right = 0, len(nums)-1
        while left <= right:
            mid = (left+right)//2
            if nums[mid] == target: return mid
            elif nums[left] == target: return left
            elif nums[right] == target: return right

            if nums[left] < nums[mid] :    # [left, mid]排序正确
                if nums[mid] > target and nums[left] < target:    # target在[left, mid]内  
                    right = mid - 1
                else:
                    left = mid + 1         
            elif nums[mid] < nums[right]:  # [mid, right]排序正确
                if nums[mid] < target and nums[right] > target:   # target在[mid, right]内  
                    left = mid + 1
                else:
                    right = mid - 1 
            else:
                return -1

        if not nums or nums[left] != target: return -1
        else: return left
153 寻找排序数组中的最小值

已知一个长度为 n 的数组,预先按照升序排列,经由 1 到 n 次 旋转 后,得到输入数组。例如,原数组 nums = [0,1,2,4,5,6,7] 在变化后可能得到:

  • 若旋转 4 次,则可以得到 [4,5,6,7,0,1,2]
  • 若旋转 7 次,则可以得到 [0,1,2,4,5,6,7]

注意,数组 [a[0], a[1], a[2], ..., a[n-1]] 旋转一次 的结果为数组 [a[n-1], a[0], a[1], a[2], ..., a[n-2]] 。

给你一个元素值 互不相同 的数组 nums ,它原来是一个升序排列的数组,并按上述情形进行了多次旋转。请你找出并返回数组中的 最小元素 。你必须设计一个时间复杂度为 O(log n) 的算法解决此问题。

假设旋转k次,则数组为 [a[n-k],a[n-k+1],...,a[0],...,a[n-k-1]] 一次二分

情况一:nums[left] < nums[mid] < nums[right] 最小值为 nums[left]

情况二:若左侧排序正确最小值只可能在右侧区间  搜索区间为[mid+1,right]

情况三:同理右侧排序正确则最小值只可能在左侧区间 搜索区间为[left,mid]   注意mid是右侧排序正确区间的最小值,也要放在搜索范围里;

当找不到递增序列时,取两个数的最小值;

class Solution(object):
    def findMin(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        left, right = 0, len(nums)-1
        while left <= right:
            mid = (left+right)//2
            if nums[left] < nums[mid] and nums[mid] < nums[right]:
                return nums[left]
            elif nums[left] < nums[mid] and nums[mid] > nums[right]:    # [left, mid]排序正确
                    left = mid + 1      
            elif nums[left] > nums[mid] and nums[mid] < nums[right]:  # [mid, right]排序正确
                    right = mid 
            else:
                return min(nums[left], nums[right])
4 寻找两个正序数组的中位数

给定两个大小分别为 m 和 n 的正序(从小到大)数组 nums1 和 nums2。请你找出并返回这两个正序数组的 中位数 。算法的时间复杂度应该为 O(log (m+n)) 。

方法一:合并两个有序数组后取中间位置的元素;                     时间复杂度O(m+n) 空间复杂度O(m+n)

将问题转换为两个有序数组中取第k小的数    k=(m+n)/2 or (m+n)/2+1

方法二:使用双指针,每次移动较小值的指针至移动k次;         时间复杂度O(m+n) 空间复杂度O(1)

方法三: 比较nums1[k/2-1]和nums2[k/2-1],对于二者中的较小值(假设nums1[k/2-1]),其在合并数组中的下标一定小于(k/2-1)*2+1<k,就不可能是目标值,此时nums1[0:k/2]也不可能含有目标值;随后根据排除掉的长度更新k后继续循环;

终止条件:某个数组为[ ],直接返回另一个数组的第k个元素;

                  k=1,直接取两数组第一个元素的最小值;

class Solution(object):
    def findMedianSortedArrays(self, nums1, nums2):
        """
        :type nums1: List[int]
        :type nums2: List[int]
        :rtype: float
        """
        def getKthElement(k):
            index1, index2 = 0, 0
            while True:
                # 特殊情况
                if index1 == m:
                    return nums2[index2 + k - 1]
                if index2 == n:
                    return nums1[index1 + k - 1]
                if k == 1:
                    return min(nums1[index1], nums2[index2])

                # 正常情况
                newIndex1 = min(index1 + k // 2 - 1, m - 1)        # 防止越界
                newIndex2 = min(index2 + k // 2 - 1, n - 1)
                pivot1, pivot2 = nums1[newIndex1], nums2[newIndex2]
                if pivot1 <= pivot2:
                    k -= newIndex1 - index1 + 1
                    index1 = newIndex1 + 1
                else:
                    k -= newIndex2 - index2 + 1
                    index2 = newIndex2 + 1
        
        m, n = len(nums1), len(nums2)
        totalLength = m + n
        if totalLength % 2 == 1:
            return getKthElement((totalLength + 1) // 2)
        else:
            return (getKthElement(totalLength // 2) + getKthElement(totalLength // 2 + 1)) / 2.

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

SAP 批次号过期了不让过账配置 OMCQ - M7 667 671消息号设置为E

系统默认&#xff0c;批次到期过账时只是警告&#xff0c;仓库希望直接卡死 这种不需要增强&#xff0c;直接配置就好了 OMCQ 找到 M7 667 编号&#xff0c;把W改成E就可以了 改成E之后&#xff0c;这个过账就直接报错了 保险起见&#xff0c;把667和671都设置为E

C++ | Leetcode C++题解之第3题无重复字符的最长子串

题目&#xff1a; 题解&#xff1a; class Solution { public:int lengthOfLongestSubstring(string s) {// 哈希集合&#xff0c;记录每个字符是否出现过unordered_set<char> occ;int n s.size();// 右指针&#xff0c;初始值为 -1&#xff0c;相当于我们在字符串的左…

Linux 磁盘分区、挂载、使用情况

Linux无论有几个分区&#xff0c;分给哪一个目录使用&#xff0c;归根结底都只有一个根目录&#xff0c;独立且唯一的文件结构。 Linux中的每个分区都是用来组成整个文件系统的一部分。 Linux采用了一种“载入”的处理方法&#xff1a;整个文件系统包含了一整套的文件目录&…

神经网络发展历程:DNN、CNN、RNN

系列文章目录 李沐《动手学深度学习》多层感知机 模型概念和代码实现 李沐《动手学深度学习》卷积神经网络 相关基础概念 李沐《动手学深度学习》卷积神经网络 经典网络模型 李沐《动手学深度学习》循环神经网络 相关基础概念 李沐《动手学深度学习》循环神经网络 经典网络模型…

深入探究Shiro反序列化漏洞

Shiro反序列化漏洞 什么是shiro反序列化漏洞环境搭建漏洞判断rememberMe解密流程代码分析第一层解密第二层解密2.1层解密2.2层解密 exp 什么是shiro反序列化漏洞 Shiro是Apache的一个强大且易用的Java安全框架,用于执行身份验证、授权、密码和会话管理。使用 Shiro 易于理解的…

docker-compse安装es(包括IK分词器扩展)、kibana、libreoffice

Kibana是一个开源的分析与可视化平台&#xff0c;设计出来用于和Elasticsearch一起使用的。你可以用kibana搜索、查看存放在Elasticsearch中的数据。 Kibana与Elasticsearch的交互方式是各种不同的图表、表格、地图等&#xff0c;直观的展示数据&#xff0c;从而达到高级的数据…

Redis的配置与优化

一、关系型数据库和非关系型数据库 1.1 关系型数据库 一个结构化的数据库创建在关系模型基础上&#xff0c;一般面向于记录&#xff0c;包括&#xff1a;Oracle、MySQL、SQLServer、Microsoft Access、DB2等 1.2 非关系型数据库 除了主流的关系型数据库外的数据库&#xff0c;都…

JimuReport积木报表 v1.7.4 正式版本发布,免费的JAVA报表工具

项目介绍 一款免费的数据可视化报表&#xff0c;含报表和大屏设计&#xff0c;像搭建积木一样在线设计报表&#xff01;功能涵盖&#xff0c;数据报表、打印设计、图表报表、大屏设计等&#xff01; Web 版报表设计器&#xff0c;类似于excel操作风格&#xff0c;通过拖拽完成报…

python高校学生兼职雇佣信息网站vue+django

而随着经济的发展&#xff0c;企业的人力成本也越来越高&#xff0c;而有些工作却存在工作时间不稳定&#xff0c;工作量不确定的特点&#xff0c;不少企业便经常雇佣兼职人员来完成其某些工作而对于另外一-些商家来&#xff0c;有不少产品需要推向校园&#xff0c;因此校园传 …

SSM框架学习——SqlSession以及Spring与MyBatis整合

SqlSession以及Spring与MyBatis整合 准备所需要的JAR包 要实现MyBatis与Spring的整合&#xff0c;很明显需要这两个框架的JAR包&#xff0c;但是只是使用这两个框架中所提供的JAR包是不够的&#xff0c;还需要配合其他包使用&#xff1a; Spring的JAR包MyBatis的JAR包Spring…

CV论文--2024.4.2

1、Unsolvable Problem Detection: Evaluating Trustworthiness of Vision Language Models 中文标题&#xff1a;无法解决的问题检测&#xff1a;评估视觉语言模型的可信度 简介&#xff1a;本文提出了一个新颖且重要的挑战&#xff0c;即视觉语言模型&#xff08;VLM&#x…

[yolox]ubuntu上部署yolox的ncnn模型

首先转换pytorch->onnx->param模型&#xff0c;这个过程可以查资料步骤有点多&#xff0c;参考blog.51cto.com/u_15660370/6408303&#xff0c;这里重点讲解转换后部署。 测试环境&#xff1a; ubuntu18.04 opencv3.4.4(编译过程省略&#xff0c;参考我其他博客) 安装…

BM25 二叉树的后序遍历(postOrder()返回值用void)

import java.util.*;/** public class TreeNode {* int val 0;* TreeNode left null;* TreeNode right null;* public TreeNode(int val) {* this.val val;* }* }*/public class Solution {/*** 代码中的类名、方法名、参数名已经指定&#xff0c;请勿修改&a…

京东云明修“价格战”,暗渡“政企云”

文&#xff5c;白 鸽 编&#xff5c;王一粟 云计算行业越来越“卷”&#xff0c;一边卷大模型&#xff0c;一边卷价格。 2024 刚一开年&#xff0c;阿里云就宣布百余款产品大降价&#xff0c;最高降幅达55%。在阿里云宣布降价后&#xff0c;京东云紧随其后宣布&#xff0…

如何用Git来查看提交记录

2024年4月2日&#xff0c;周二上午 使用 git log 命令查看提交记录。这会列出所有的提交历史&#xff0c;按照时间顺序从最新的提交到最旧的提交显示。默认情况下&#xff0c;git log 会以一种格式化的方式显示提交信息&#xff0c;包括提交哈希值、作者、提交日期和提交信息等…

https安全性 带给im 消息加密的启发

大家好&#xff0c;我是蓝胖子&#xff0c;在之前# MYSQL 是如何保证binlog 和redo log同时提交的&#xff1f;这篇文章里&#xff0c;我们可以从mysql的设计中学会如何让两个服务的调用逻辑达到最终一致性&#xff0c;这也是分布式事务实现方式之一。今天来看看我们能够从http…

深入解析大数据体系中的ETL工作原理及常见组件

** 引言 关联阅读博客文章&#xff1a;探讨在大数据体系中API的通信机制与工作原理 关联阅读博客文章&#xff1a;深入理解HDFS工作原理&#xff1a;大数据存储和容错性机制解析 ** 在当今数字化时代&#xff0c;大数据处理已经成为了企业成功的重要组成部分。而在大数据处…

(C)1007 素数对猜想

1007 素数对猜想 问题描述 输入样例&#xff1a; 20 输出样例&#xff1a; 4 解决方案&#xff1a; #include<stdio.h> #include<string.h> #include<math.h> int main(){int n,d;int a[100000];int flag,jishu0;scanf("%d",&n);memset(a,-1,…

将 Three 带到 Vue 生态系统,TresJs 中文文档上线

将 Three 带到 Vue 生态系统&#xff0c;TresJs 中文文档上线 中文文档上线入门指南 ThreeJS 在创建 WebGL 3D 网站方面是一个奇妙的库&#xff0c;同时他也是一个保持不断更新的库&#xff0c;一些对其封装的维护者&#xff0c;如 TroisJS&#xff0c;往往很难跟上其所有的更…

docker容器添加新端口映射的步骤及`wsl$`目录的作用

在Docker容器已经创建后&#xff0c;需要添加新的端口映射&#xff0c;即对已经存在的Docker容器添加新的端口映射&#xff0c;可以通过以下步骤来添加&#xff0c;即通过修改配置文件的方法。 如何新增端口映射&#xff1f; 查找容器的hash值 docker inspect [容器id或名称…