0115 查找算法Day4

news2024/9/21 16:46:56

剑指 Offer 03. 数组中重复的数字

在一个长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。

示例 1:

输入:
[2, 3, 1, 0, 2, 5, 3]
输出:2 或 3 

class Solution {
    public int findRepeatNumber(int[] nums) {

    }
}

解题思路

数组元素的 索引 和 值 是 一对多 的关系。
因此,可遍历数组并通过交换操作,使元素的 索引 与 值 一一对应(即 nums[i] = i )。因而,就能通过索引映射对应的值,起到与字典等价的作用。

遍历中,第一次遇到数字 x 时,将其交换至索引 x 处;而当第二次遇到数字 x 时,一定有 nums[x]=x ,此时即可得到一组重复数字。

算法流程:
遍历数组 nums ,设索引初始值为 i = 0 :

若 nums[i] =i : 说明此数字已在对应索引位置,无需交换,因此跳过;
若 nums[nums[i]] = nums[i] : 代表索引 nums[i]处和索引 i 处的元素值都为nums[i] ,即找到一组重复值,返回此值 nums[i] ;
否则: 交换索引为 i 和 nums[i] 的元素值,将此数字交换至对应索引位置。
若遍历完毕尚未返回,则返回 -1 。

 

 

 

 

 

 

 

 代码如下:

class Solution {
    public int findRepeatNumber(int[] nums) {
        int i = 0;
        while(i < nums.length) {
            if(nums[i] == i) {
                i++;
                continue;
            }
            if(nums[nums[i]] == nums[i]) return nums[i];
            int tmp = nums[i];
            nums[i] = nums[tmp];
            nums[tmp] = tmp;
        }
        return -1;
    }
}

剑指 Offer 53. 在排序数组中查找数字

统计一个数字在排序数组中出现的次数。

示例 1:

输入: nums = [5,7,7,8,8,10], target = 8
输出: 2
示例 2:

输入: nums = [5,7,7,8,8,10], target = 6
输出: 0

class Solution {
    public int search(int[] nums, int target) {

    }
}

解题思路

算法解析:
初始化: 左边界 i = 0 ,右边界 j = len(nums) - 1 。
循环二分: 当闭区间 [i, j]无元素时跳出;
计算中点 m = (i + j) / 2(向下取整);
若 nums[m] < target ,则target 在闭区间[m+1,j] 中,因此执行 i = m + 1;
若 nums[m] > target ,则 target 在闭区间 [i, m - 1] 中,因此执行 j = m - 1;
若 nums[m] = target,则右边界right 在闭区间[m+1,j] 中;左边界left 在闭区间 [i,m−1] 中。因此分为以下两种情况:
若查找 右边界 right ,则执行 i = m + 1;(跳出时 i 指向右边界)
若查找 左边界 left ,则执行j=m−1 ;(跳出时 j 指向左边界)
返回值: 应用两次二分,分别查找right 和 left ,最终返回 right - left - 1即可

 

 

 

 

 

代码如下:

class Solution {
    public int search(int[] nums, int target) {
        // 搜索右边界 right
        int i = 0, j = nums.length - 1;
        while(i <= j) {
            int m = (i + j) / 2;
            if(nums[m] <= target) i = m + 1;
            else j = m - 1;
        }
        int right = i;
        // 若数组中无 target ,则提前返回
        if(j >= 0 && nums[j] != target) return 0;
        // 搜索左边界 right
        i = 0; j = nums.length - 1;
        while(i <= j) {
            int m = (i + j) / 2;
            if(nums[m] < target) i = m + 1;
            else j = m - 1;
        }
        int left = j;
        return right - left - 1;
    }
}

以上代码显得比较臃肿(两轮二分查找代码冗余)。为简化代码,可将二分查找右边界 right 的代码 封装至函数 helper() 。 

 


class Solution {
    public int search(int[] nums, int target) {
        return helper(nums, target) - helper(nums, target - 1);
    }
    int helper(int[] nums, int tar) {
        int i = 0, j = nums.length - 1;
        while(i <= j) {
            int m = (i + j) / 2;
            if(nums[m] <= tar) i = m + 1;
            else j = m - 1;
        }
        return i;
    }
}

剑指 Offer 53. 0~n-1 中缺失的数字 

一个长度为n-1的递增排序数组中的所有数字都是唯一的,并且每个数字都在范围0~n-1之内。在范围0~n-1内的n个数字中有且只有一个数字不在该数组中,请找出这个数字。

示例 1:

输入: [0,1,3]
输出: 2
示例 2:

输入: [0,1,2,3,4,5,6,7,9]
输出: 8

class Solution {
    public int missingNumber(int[] nums) {

    }
}

解题思路

算法解析:
初始化: 左边界 i = 0,右边界j=len(nums)−1 ;代表闭区间[i,j] 。
循环二分: 当 i≤j 时循环 (即当闭区间 [i,j] 为空时跳出) ;
计算中点 m=(i+j)/2 ;
若 nums[m] = m ,则 “右子数组的首位元素” 一定在闭区间[m+1,j] 中,因此执行i=m+1;
若 nums[m] !=m ,则 “左子数组的末位元素” 一定在闭区间 [i,m−1] 中,因此执行j=m−1;
返回值: 跳出时,变量 i 和 j 分别指向 “右子数组的首位元素” 和 “左子数组的末位元素” 。因此返回 i 即可。

 

 

 

 

 

代码如下:


class Solution {
    public int missingNumber(int[] nums) {
        int i = 0, j = nums.length - 1;
        while(i <= j) {
            int m = (i + j) / 2;
            if(nums[m] == m) i = m + 1;
            else j = m - 1;
        }
        return i;
    }
}

 

 

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

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

相关文章

Linux-CPU之平均负载

一般我们觉得系统变慢了&#xff0c;都会执行 top 或者 uptime 命令&#xff0c;来了解系统的负载情况。 uptime11:29:06 up 0 min, 2 users, load average: 1.21, 0.29, 0.10// 当前时间 // 系统运行时间 // 正在登录用户数 //1 分钟、5 分钟、15 分钟的平均负载概念&…

补知识点:Stream API

一、创建Stream 首先创建Stream的话&#xff0c;有四种创建方式&#xff1a; 注&#xff1a; 第一种集合的方式是最常用的 package com.atguigu.gulimall.gateway;import com.atguigu.gulimall.streamapi.Employee; import com.atguigu.gulimall.streamapi.EmployeeData; impo…

【应用】Docker

DockerDocker 的安装基本安装流程配置镜像加速Docker 常用命令镜像相关命令容器相关命令DockerfileDockerfile 常用指令Dockerfile 简单使用案例Dockerfile 构建 java 项目镜像Docker ComposeDocker compose 基本参数services 配置参数Docker 的安装 基本安装流程 使用虚拟机…

Linux JDK8下载安装

JDK安装 整体步骤介绍 操作步骤: 1 查看自己linux版本位 getconf LONG_BIT(64位) 2. 下载jdk的安装包 这里提供三种方法下载: (以jdk-8u171-linux-x64.tar.gz为例) 2.1 官网下载jdk: 官网: https://www.oracle.com/downloads/ jdk最新版本下载: https://www.oracle.com…

带你玩转序列模型之seq2seq模型定向(集束)搜索

目录 一.基础模型 二.选择最可能的句子 三.定向搜索 四.改进定向搜索 五.定向搜索的误差分析 一.基础模型 在这一周&#xff0c;你将会学习seq2seq&#xff08;sequence to sequence&#xff09;模型&#xff0c;从机器翻译到语音识别&#xff0c;它们都能起到很大的作用…

【数据结构1】数据结构的基本概念

数据结构的基本概念 数据&#xff1a;数据是信息的载体&#xff0c;是描述客观事物属性的数、字符及所有能输入到计算机中并被计算机程序识别和处理的符号的集合。数据是计算机程序加工的原料。 数据元素、数据项&#xff1a;数据元素是数据的基本单位&#xff0c;通常作为一…

以太网 TCP协议(TCP交互过程中出现丢包时的解决机制-列举部分)

2.7.3 以太网 TCP协议&#xff08;TCP交互过程中出现丢包时的解决机制-列举部分&#xff09; 参考&#xff1a;CSDN_TCP的重传机制_博主.Pr Young&#xff0c;对描述进行了整理与结合个人的理解进行编写。 一、超时重传机制 在发送数据时&#xff0c;设定一个定时器&#xff0c…

Ubuntu下cmake使用入门

CMake是一个跨平台的安装&#xff08;编译&#xff09;工具&#xff0c;可以用简单的语句来描述所有平台的安装(编译过程)。他能够输出各种各样的makefile或者project文件。其包含自己的语法结构&#xff0c;只要按照其语法编写成CMakeLists.txt&#xff0c;然后camke程序就能对…

MAML:User Diverse Preference Modeling by Multimodal AttentiveMetric Learning

一、摘要 大多数现有的推荐系统用特征向量表示用户的偏好&#xff0c;当预测该用户对不同项目的偏好时&#xff0c;假设该特征向量是固定的。然而&#xff0c;同一个向量不能准确地捕捉用户对所有项目的不同偏好&#xff0c;特别是在考虑各种项目的不同特征时。为了解决这个问…

【应用】Kubernetes

Kubernetesk8s 安装流程安装前配置安装 docker 以及 k8s 组件初始化 k8s 集群测试使用&#xff1a;安装 kubernetes-dashboardk8s 基础概念k8s 核心技术概念k8s 内部组件k8s 中的 IP 地址K8S 服务暴露的三种方式k8s 安装流程 k8s-masterk8s-node01k8s-node02192.168.86.140192…

【编程题】【Scratch四级】2022.09 三个数排序

三个数排序 输入三个数&#xff0c;比较三个数的大小&#xff0c;并将这三个数按照从小到大的顺序说出。 1. 准备工作 &#xff08;1&#xff09;保留小猫角色&#xff0c;默认位置&#xff1b; &#xff08;2&#xff09;白色背景。 2. 功能实现 &#xff08;1&#xff…

Java基于SSM框架的教室预约申请管理系统 毕业设计

本教室管理系统主要包括系统用户管理模块、楼层信息管理模块、校内新闻管理、教室信息管理、登录模块、和退出模块等多个模块。它帮助教室管理实现了信息化、网络化,通过测试,实现了系统设计目标,相比传统的管理模式,本系统合理的利用了教室管理数据资源,有效的减少了教室管理的…

四旋翼无人机学习第13节--Padstack Editor的简单使用

文章目录0 前言1 绘制MP2120 QFN10封装焊盘(初步学习)1.1 数据手册确定焊盘种类1.2 软件设置焊盘11.3 软件设置焊盘22 绘制DM9000A LQFP48L封装焊盘(初步学习)2.1 数据手册确定焊盘种类2.2 软件设置焊盘3 绘制STC89C51 PDIP-40封装通孔焊盘(初步学习)3.1 数据手册确定焊盘种类3…

【Spring源码系列】Bean生命周期-Bean销毁

前言 Spring给我们提供了一种当bean销毁时调用某个方法的方式。那么&#xff0c;Spring底层到底是如何实现的呢&#xff1f;接下来&#xff0c;我们将从源码案例的方式来解析&#xff1a;spring如何实现当bean销毁时调用某个方法的。 一、Bean销毁介绍 bean销毁的时机 当sp…

[附源码]计算机毕业设计springboot智能衣橱APP

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

数据增强 - 当数据有限时如何使用深度学习(一)

本文是对图像的深度学习数据增强技术的全面综述前言我们都遇到过这种情况&#xff1a;您有一个可以使用机器学习模型实现的机会&#xff0c;但当您打开网络浏览器并搜索相关数据&#xff0c;很有可能&#xff0c;您会发现一个只有几百张图像的数据集。您记得最受欢迎的数据集的…

【项目_03】日历的回显、搭建热门精选、下拉加载更多、搜索框搭建 | 基于Vue3全家桶

&#x1f4ad;&#x1f4ad; ✨: 日历的回显、搭建热门精选、下拉加载更多、搜索框搭建 | 旅途拾景   &#x1f49f;&#xff1a;东非不开森的主页   &#x1f49c;: 心若有所向往&#xff0c;何惧道阻且长&#x1f49c;&#x1f49c;   &#x1f338;: 如有错误或不足之处&…

Android入门第38天-使用随鼠标移动的圆点来熟悉onTouchEvent

简介 平时包括之前的例子大量是基于TouchListener如&#xff1a;onClick这种一类的事件。 今天给大家带来的是TouchListener与OnTouchEvent的比较&#xff0c;以及多点触碰的知识点&#xff01; TouchListener是基于监听的&#xff0c;而OnTouchEvent则是基于回调的&#xff…

SNMP协议——网络管理概述

作者简介&#xff1a;一名在校云计算网络运维学生、每天分享网络运维的学习经验、和学习笔记。 座右铭&#xff1a;低头赶路&#xff0c;敬事如仪 个人主页&#xff1a;网络豆的主页​​​​​​ 目录 前言 一.网络管理概述 1.网络管理概念 2.网络管理功能 1.配置管理 …

Xshell连接如何记住用户秘钥文件

场景描述 服务器ssh登录有2种常用的方式&#xff1a; 方式1&#xff1a;用户密码认证&#xff0c;登录时输入用户名和密码。方式2&#xff1a;公钥认证(Public Key User Authentication)&#xff0c;登录时提供用户名私钥。公钥需要存储一份在服务器上该用户的~/.ssh/authori…