局部最小值问题

news2024/12/22 19:54:40

局部最小值问题

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

自写:

	// arr 相邻的数不相等! 返回一个局部最小的下标
    public static int oneMinIndex(int[] arr) {
        if(arr == null || arr.length == 0) {
            return -1;
        }
        if(arr.length == 1) {
            return 0;
        }
        int L = 0;
        int R = arr.length - 1;
        if(arr[L] < arr[L + 1]) {
            return L;
        }
        if(arr[R] < arr[R - 1]) {
            return R;
        }
        // 之后是两边下陷的情况
        while(L <= R) {
            int mid = (L + R) / 2;
            if (mid -1 >= L && mid +1 <= R && arr[mid] < arr[mid + 1] && arr[mid] < arr[mid - 1]) {
                return mid;
            }
            if(mid -1 >= L && arr[mid] > arr[mid - 1]) {
                R = mid - 1;
                continue;
            }
            if(mid +1 <= R && arr[mid] > arr[mid + 1]) {
                L = mid + 1;
            }
            // L与R相邻的时候,直接返回最小的那个
            if(mid == L || mid == R) {
                return arr[L] > arr[R] ? R : L;
            }
        }
        return -1;
    }

左神:

// arr 相邻的数不相等! 返回一个局部最小的下标
    public static int oneMinIndex2(int[] arr) {
        if(arr == null || arr.length == 0) {
            return -1;
        }
        if(arr.length == 1) {
            return 0;
        }
        int L = 0;
        int R = arr.length - 1;
        if(arr[L] < arr[L + 1]) {
            return L;
        }
        if(arr[R] < arr[R - 1]) {
            return R;
        }
        // 之后是两边下陷的情况
        while(L < R-1) {
            int mid = (L + R) / 2;
            if (arr[mid] < arr[mid + 1] && arr[mid] < arr[mid - 1]) {
                return mid;
            }
            if(arr[mid] > arr[mid - 1]) {
                R = mid - 1;
                continue;
            }
            if(arr[mid] > arr[mid + 1]) {
                L = mid + 1;
            }
        }
        return arr[L] < arr[R] ? L : R;
    }

在这里插入图片描述
在这里插入图片描述

总结一下:

	public static int oneMinIndex3(int[] arr) {
        if (arr == null || arr.length == 0) {
            return -1;
        }
        int N = arr.length;
        if (N == 1) {
            return 0;
        }
        //到这,arr的长度是大于等于2的
        if (arr[0] < arr[1]) {
            return 0;
        }
        if (arr[N - 1] < arr[N - 2]) {
            return N - 1;
        }
        int L = 0;
        int R = N - 1;
        int ans = -1;
        while (L <= R) {
            int mid = (L + R) / 2;
            //中间位置是否是最小,[mid-1] > [mid] < [mid+1]
            if (arr[mid] < arr[mid - 1] && arr[mid] < arr[mid + 1]) {
                ans = mid;
                break;

                //不同时小,下面两个判断选一个就行
            } else if (arr[mid] > arr[mid - 1]) {
                R = mid;
            } else {//arr[mid] > arr[mid + 1]
                L = mid;
            }
        }
        return ans;
    }
}

L == 0 ,R == n - 1

0 与 n - 1位置上一定不是局部最小值,而 [ 1 , n-2 ] 之间一定有局部最小值,所以 mid (mid:锁定局部最小

值的)不可能来到下标 0 与 n - 1 的位置,下标 0 与 n - 1 作为一个缓冲区(如果来到0或n-1的旁边,0与n - 1

可作为一个缓冲区,就不会出现mid-1或者mid+1越界的情况)。如果mid位置是局部最小值就返回了,如果没

返回说明mid位置不是局部最小值,我们就令L == mid 或者是 R == mid,这样 L 与 R 也是一个缓冲区,L与R

之间一定有局部最小值。还有就是,不会有(L == 0&& R == 1 ) || (L == N-2 && R == N-1 )

的情况,如果出现上述的情况说明一定没有局部最小值(L与R是缓冲区,中间没有值),然而事实是一定有

局部最小值。

这个方法的关键是:下标0,N-1的区域做缓冲区,L与R做缓冲区。所以没有越界的风险。

	public static int getLessIndex(int[] arr) {
        if (arr == null || arr.length == 0) {
            return -1;
        }
        if (arr.length == 1 || arr[0] < arr[1]) {
            return 0;
        }
        if (arr[arr.length - 1] < arr[arr.length - 2]) {
            return arr.length - 1;
        }
        int left = 1;
        int right = arr.length - 2;
        int mid = 0;
        while (left <= right) {
            mid = (left + right) / 2;
            if (arr[mid] > arr[mid - 1]) {
                right = mid - 1;
            } else if (arr[mid] > arr[mid + 1]) {
                left = mid + 1;
            } else {
                return mid;
            }
        }
        // 这个地方return谁都是对的,因为一定有区域最小值
        return left; 
    }

L == 1 ,R == n - 2

如果mid位置是局部最小值就返回了,如果没返回说明mid位置不是局部最小值,我们就

令L == mid + 1 或者是 R == mid - 1,mid一定不是局部最小值,但是mid+1与mid-1可能是局部最小值。所以

【L,R】L与R之间都是 “好的” 都是有可能是局部最小值的区域,剔除不是局部最小值的部分,在是局部最小

值的区域寻找。

这个方法的关键:[L , R] L与R之间都是“好的”部分(可能是局部最小值的部分)不可能来到下标 0,n - 1位

置,并且下标 0,n - 1位置可以作为一个缓冲,所以不会出现越界的状况。

// arr 相邻的数不相等! 返回一个局部最小的下标
    public static int oneMinIndex(int[] arr) {
        if(arr == null || arr.length == 0) {
            return -1;
        }
        if(arr.length == 1) {
            return 0;
        }
        int L = 0;
        int R = arr.length - 1;
        if(arr[L] < arr[L + 1]) {
            return L;
        }
        if(arr[R] < arr[R - 1]) {
            return R;
        }
        // 之后是两边下陷的情况
        while(L <= R) {
            int mid = (L + R) / 2;
            if (mid -1 >= L && mid +1 <= R && arr[mid] < arr[mid + 1] && arr[mid] < arr[mid - 1]) {
                return mid;
            }
            if(mid -1 >= L && arr[mid] > arr[mid - 1]) {
                R = mid - 1;
                continue;
            }
            if(mid +1 <= R && arr[mid] > arr[mid + 1]) {
                L = mid + 1;
            }
            // L与R相邻的时候,直接返回最小的那个
            if(mid == L || mid == R) {
                return arr[L] > arr[R] ? R : L;
            }
        }
        return -1;
    }

L == 0 R == n - 1

下标为0 和 n - 1的位置是一个缓冲区。

如果mid位置是局部最小值就返回了,如果没返回说明mid位置不是局部最小值,我们就

令L == mid + 1 或者是 R == mid - 1。

刚开始L == 0,R == n - 1是一个缓冲区,仅当R == mid - 1的时候,R失去了缓冲区的作用,但是L仍然是缓冲

区,因为R是“好的”,所以当R来到下标为1的位置就会出现越界的风险,因为此时mid指向L,即0下标。

而上面的方法1不会有问题的原因是:L与R都是缓冲区,不会有(L == 0&& R == 1 ) || (L == N-2 && R == N-1 )

的情况,如果出现上述的情况说明一定没有局部最小值(L与R是缓冲区,中间没有值),然而事实是一定有

局部最小值。

而本方法就会有(L == 0&& R == 1 )的情况出现,因为R 不是缓冲区。一遍是缓冲区一遍不是缓冲区,就有可

能越界。

写代码的时候别写方法三这种半吊子代码。

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

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

相关文章

C++判断大端小端

C判断大端小端 1. 基础知识 大端小端其实表示的是数据在存储器中的存放顺序。 大端模式&#xff1a;数据的高字节存放在内存的低地址中&#xff0c;而低字节则存放在高地址中。地址由小到大增加&#xff0c;数据则从高位向低位存放&#xff0c;这种存放方式符合人类的正常思维…

Hadoop/HbBase/Hive/HDFS/MapReduce都是什么?

目录 一图胜万言&#xff01;&#xff01; 解释说明 1. hadoop 2. hive 3. hbase 总结 一图胜万言&#xff01;&#xff01; 解释说明 1. hadoop 它是一个分布式计算分布式文件系统&#xff0c;前者其实就是 MapReduce&#xff0c;后者是 HDFS 。后者可以独立运行&…

特瑞仕|关于无线射频

无线射频&#xff08;Radio Frequency, RF&#xff09;是指在一定频率范围内&#xff0c;通过无线电波进行通信和传输信息的技术。随着移动通信、物联网、智能家居等领域的不断发展&#xff0c;无线射频技术已经成为现代社会中不可或缺的一部分。本文将从以下几个方面对无线射频…

打印机无法扫描的原因及解决方法

在家庭和办公环境中&#xff0c;打印机已成为不可或缺的设备。它不仅可以打印文件&#xff0c;还可以扫描文档并将它们转换为数字数据。但有时&#xff0c;打印机可能无法扫描文档或图片。以下是可能导致这些问题的原因和解决方法。 出现打印机无法扫描的原因&#xff1a; 1.…

web基础和http协议

文章目录 一、web基础1.1dns的概念1.2网页的概念1.3HTML的概念1.4静态网页1.5动态网络 二、HTTP协议2.1什么是HTTP协议2.2HTTP的版本协议2.3HTTP的请求方法2.4HTTP的状态码2.5HTTP 请求流程分析 一、web基础 1.1dns的概念 dns用作域名解析&#xff0c;有正向解析和反向解析两…

protobuf全局环境搭建

一、安装npm 1.测试是否安装npm 如果未出现npm 不是内部或外部命令&#xff0c;则先安装npm npm是NodeJs的包管理器&#xff08;Node Package Manager&#xff09; 所以我们要安装npm&#xff0c;其实就是安装NodeJs&#xff0c;进入NodeJs官网 下载完成之后&#xff0c;安装…

7.性能测试

目录 一、常见的性能问题 二、为啥要进行性能测试&#xff1f; 三、确定性能测试的需求&#xff08;性能指标&#xff0c;量化&#xff09; 1.关键性能指标分析 2.关键业务的分析 四、不同维度衡量系统的性能 1.研发人员 2.系统运维人员 3.用户 4.性能测试人员 五、性…

力扣 695. 岛屿的最大面积

一、题目描述 给你一个大小为 m x n 的二进制矩阵 grid。 岛屿是由一些相邻的 1&#xff08;代表土地&#xff09;构成的组合&#xff0c;这里的相邻要求两个 1 必须在水平或者竖直的四个方向上相邻。你可以假设 grid 的四个边缘都被 0&#xff08;代表水&#xff09;包围着。…

论文分享 A ConvNet for the 2020s

摘要 视觉识别的“咆哮的 20 年代”始于 Vision Transformers (ViTs) 的引入&#xff0c;它迅速取代了 ConvNets&#xff0c;成为最先进的图像分类模型。另一方面&#xff0c;vanilla ViT 在应用于对象检测和语义分割等一般计算机视觉任务时面临困难。正是层次化的 Transforme…

SpringBoot 3.1现已推出,惊艳新特性带来前所未有的开发体验

一、介绍 1.1 新特性概述 经过半年的沉淀 Spring Boot 3.1于2023年5月18日正式发布了&#xff0c;带来了许多令人兴奋的新特性和改进。本篇博客将详细介绍Spring Boot 3.1的新特性、升级说明以及核心功能的改进。 同时&#xff0c;2.6.x 版本线已经停止维护了&#xff0c;最新…

02SpringCloud Nacos注册中心和配置中心与Sentinel服务熔断和流控

Nacos注册中心和配置中心 Nacos 是 Alibaba 开发的用于微服务管理的平台&#xff0c;核心功能&#xff1a;服务注册与发现和集中配置管理。 Nacos 作为服务注册发现组件&#xff0c;可以替换Spring Cloud 应用中传统的服务注册于发现组件&#xff0c;如&#xff1a;Eureka、C…

XML和JSON格式转换成txt

XML如下这种&#xff1a; 转换代码 import os import xml.etree.ElementTree as ET# xml文件存放目录(修改成自己的文件名) input_dir rC:\121\Annotations# 输出txt文件目录&#xff08;自己创建的文件夹&#xff09; out_dir rC:\121\txtclass_list []# 获取目录所有xml文…

pix2pixHD代码---数据集处理

在train文件中&#xff1a;其中dataset是dataloader的方法&#xff0c;而dataloader等于CreateDataLoader。 所以我们跳到CreateDataLoader&#xff1a; 在CreateDataLoader中返回的是dataset_loader&#xff0c;是来自于CustomDatasetDataLoader。切调用了initialize。因为C…

零次学习(Zero-Shot Learning)

零次学习&#xff08;Zero-Shot Learning&#xff09; 零样本学习zero-shot learning&#xff0c;是最具挑战的机器识别方法之一。2009年&#xff0c;Lampert 等人提出了Animals with Attributes数据集和经典的基于属性学习的算法&#xff0c;开始让这一算法引起广泛关注。 零…

qt quick(qml)通过arcgis导入自定义格式地图(Windows 版本)

参考ArcGIS Maps SDK for Qt 参考Display a map 安装 预先安装的软件 安装ArcGIS SDK 点击ArcGIS Maps SDK for Qt 注册账号 要注册成developer版本用户的&#xff0c;不然之后可能没办法生成API 下载 下载之后安装&#xff0c;一路next就可以了 在QT中创建ArcGIS项目…

CMOS图像传感器——TDI CIS(2)

在之前的文章 CMOS图像传感器——TDI CIS_tdi相机的工作原理_沧海一升的博客-CSDN博客时间延迟积分(Time-Delay Integration, TDI)技术是一种特殊的成像模式https://blog.csdn.net/qq_21842097/article/details/119873386 对CMOS TDI图像传感器做了基本介绍,这里我们…

django项目结合vue执行

开发环境下直接把vue打包后的文件放在django项目&#xff0c;启动前端项目直接打包即可 注意事项&#xff1a; settings.py文件 TEMPLATES [ { ‘BACKEND’: ‘django.template.backends.django.DjangoTemplates’, # ‘DIRS’: [], ‘DIRS’: [os.path.join(BASE_DIR,‘front…

Java基础面试题突击系列5

&#x1f469;&#x1f3fb; 作者&#xff1a;一只IT攻城狮 &#xff0c;关注我不迷路 ❤️《java面试核心知识》突击系列&#xff0c;持续更新… &#x1f490; 面试必知必会学习路线&#xff1a;Java技术栈面试系列SpringCloud项目实战学习路线 &#x1f4dd;再小的收获x365天…

mac 切换java jdk版本 java8 java11

1. 终端执行命令 查看本地各版本jdk&#xff1a;mac通常默认安装了jdk1.8 安装目录是 /Library/Java/JavaVirtualMachines/ cd /Library/Java/JavaVirtualMachines/ ls 2. 上述命令列出的各版本目录名 后&#xff0c;在全局配置文件.bash_profile中新增上面命令列出的各…

四月,收割12家offer,面试也太容易了吧....

前言 下面是我根据工作这几年来的面试经验&#xff0c;加上之前收集的资料&#xff0c;整理出来350道软件测试工程师 常考的面试题。字节跳动、阿里、腾讯、百度、快手、美团等大厂常考的面试题&#xff0c;在文章里面都有 提到。 虽然这篇文章很长&#xff0c;但是绝对值得你…