算法通过村第三关-数组青铜笔记|单调数组

文章目录

  • 前言
  • 单调数组问题
  • 搜索插入位置:
  • 数组合并问题:
  • 总结


前言

提示:本份真诚面对自己、坦然无碍面对他人,就是优雅。

数组中的比较经典性问题:

  1. 单调数组问题
  2. 数组合并问题

单调数组问题

参考例子:896. 单调数列 - 力扣(LeetCode)
在这里插入图片描述
在这里插入图片描述
这里先思考一下:数组有序是前提,通过增/减两种状态,可以采用不同的策略。

  1. 对于所有的 i <= j 使得 a[i] <= a[j] 则说明数组 a 是单调递增的,反之,对所有的 i <= j ,使得所有的a[i] >= a[j],那么数组 a 是单调递增的。
  2. 所有遍历数组执行判断就可以解决,由于存在两种情况,我们需要两次循环就可以

展示代码🥰

 /**
     * 第一种方法,两次遍历确定,第一次确定是否递增 ,第二次
     *
     * @param nums
     * @return
     */
    public static boolean isMonotonic(int[] nums) {
        return isSorted(nums, true) || isSorted(nums, false);
    }

    public static boolean isSorted(int[] nums, boolean increasing) {
        int n = nums.length;
        for (int i = 0; i < n - 1; ++i) {
            if(increasing){ // 增 
                if (nums[i] > nums[i + 1]) {
                    return false;
                }
            }else{
                if (nums[i] < nums[i + 1]) {
                    return false;
                }
            }
        }
        return true;
    }

当然这样写是可以通过测试的,但是显得有点繁琐了😁,需要遍历两次,想一下这里需要怎么优化呢💡

我们关注一下 i 和 i + 1出现的位置 nums[i] > nums[i + 1], 而在另外的一个地方 j 和 j + 1 出现的位置nums[j] < num[j + 1],那是不是说明就是单调的?这样的化我们可以使用两个变量标记一下,代码如下:

    /**
     * 第二种方式,一次遍历确定
     *如果是递增的就一定不能出现递减的相邻元素,
     * 如果出现递减的就一定不能出现递增的相邻元素。
     * @param nums
     * @return
     */
    public static boolean isMonotonic_2(int[] nums) {
        boolean des = true, inc = true;
        int n = nums.length;
        for (int i = 0; i < n - 1; i++) {
            if (nums[i] > nums[i + 1]) {
                inc = false;
            }
            if (nums[i] < nums[i + 1]) {
                des = false;
            }
        }
        return des || inc;
    }

技巧:两元式结果的特殊处理,|| 运算的运用。

搜索插入位置:

数组单调性,是一个重要的信息,很多时候要将特定的元素插入到有序序列,并且保证插入后的顺序依然有序,比如力扣的 35 题:35. 搜索插入位置 - 力扣(LeetCode)

在这里插入图片描述
在这里插入图片描述
这个问题让我们将元素位置返回,比较简单,只需要遍历一边数组就可以找到答案。当然想这样的问题,如何快速的寻找目标元素,我们需要有 二分的概念。以后但凡遇到单调序列中查找的情况,脑海中马上想到二分,迅速反应。

题解:

class Solution {
    public int searchInsert(int[] nums, int target) {
        int n = nums.length;
        for(int i = 0; i < n; i++){
            if(nums[i] >= target){
                return i;
            }
        }
        // 出现再最后一个
        return n;
    }
}

这里贴一下代码提供思考💡( 二分思想)

 public static int searchInsert(int[] nums, int target) {
      // 拿到 数组长度
        int n = nums.length;
        // 确定左右
        int left = 0, right = n - 1, ans = n;
        while(left <= right){// 思考这里问什么是 小于等于
            // 确定 中间值
            int mid = (right - left) / 2 + left;
            if (nums[mid] >= target){
                ans = mid;
                right = mid - 1;
            }else {
                left = mid + 1;
            }
        }
        return ans;
    }

数组合并问题:

数组合并是将两个或者多个有序数组合并成一个新的数组。当然这个问题本事不是很难,但是要写的出彩,确实需要花费一些功夫的,这个问题也是比较经典的问题。

先来看看力扣 88 题,88. 合并两个有序数组 - 力扣(LeetCode)
在这里插入图片描述
对于这个问题嘛,简单的思路就是

  1. 将nums2 添加在nums1 的后面
  2. 排序
/**
     * 方法1:先合并再排序实现排序
     *
     * @param nums1 第一个数组
     * @param nums1_len 第一个数组的长度
     * @param nums2  第二个数组,将nums2合并到nums1中
     * @param nums2_len 第二个数组的长度
     */
    public static void merge1(int[] nums1, int nums1_len, int[] nums2, int nums2_len) {
        for (int i = 0; i < nums2_len; i++) {
            nums1[nums1_len + i] = nums2[i];
        }
        Arrays.sort(nums1);
    }

当然这样写太没有技术含量了,面试官也不喜欢。这道题的关键是将nums2合并到nums1 中并且还要保证有序。因为nums1是数组不能强行插入。如果从前面向后面出插入,数组nums1后面的元素会多次移动,代价太高了。此时再借助一个数组就可以解决这个问题 ans,把选好的数组元素放入ans中,最后返回,很好的解决以上为题。

这样的化面试官会接着向下考察:可以优化一下,或者不申请数组。(专业的说法是,空间复杂度O(n),可以采用O(1)的方法实现?

比较好的方式从后向前插入,nums1 和 nums2 的元素是固定的,所以排序后最远位置一定是nums1 和 nums2 中最大的那一个,一次类推,每次找最大的,就可以实现从后向前填了,展示一下代码:


    /**
     * 方法2:两个数组从后向前逐步合并
     *
     * @param nums1
     * @param nums1_len
     * @param nums2
     * @param nums2_len
     */
    public static void merge2(int[] nums1, int nums1_len, int[] nums2, int nums2_len) {
       int  n = nums1_len + nums2_len - 1;
       int  len_1 = nums1_len - 1, len_2 = nums2_len - 1;
       while (len_1 >= 0 && len_2 >= 0){
           if (nums1[len_1] >= nums2[len_2]){
               nums1[n--] = nums1[len_1--];
           }else if (nums1[len_1] < nums2[len_2]){
               nums1[n--] = nums2[len_2--];
           }
       }
       // 有剩余
        while(len_1 != -1){
            nums1[n--] = nums1[len_1--];
        }
        while(len_2 != -1){ // 为甚是-1
            nums1[n--] = nums2[len_2--];
        }
    }

思考一下这个代码是不是还可以优化一下💡


总结

提示:单调数组是很重要的一块,二分思想的引入。

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

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

相关文章

vue3+element-plus表格默认排序default-sort失效问题

场景 在使用动态数据渲染的场景&#xff0c;el-table设置默认属性default-sort失效。 原因 el-table的default-sort属性是针对静态数据的&#xff0c;如果是动态数据&#xff0c;default-sort则无法监听到。 案例&#xff1a;静态数据 <template><el-table:data&…

全面拥抱AI时刻来临?基于AI技术助力养猪产仔是否可行?

这两天看到一篇论文&#xff0c;蛮有意思的&#xff0c;技术层面倒没有什么新颖的点&#xff0c;主要是落地应用场景比较贴近现实&#xff0c;文章主要就是应用yolov5来开发构建了一套母猪产仔智能化检测预警模型&#xff0c;从而来降低大型养殖场中人工成本。一起来简单看下吧…

比例电磁铁控制放大器

GP63系列比例电磁铁应用于电液比例控制系统中&#xff0c;与比例控制放大器配套使用共同控制力士(REXROTH)型十通径螺纹比例阀。在额定行程及额定电流范围内&#xff0c;其输出力与输入电流成比例&#xff0c;通过内置反力弹簧&#xff0c;改变了输出力的特性&#xff0c;使系统…

leetcode358周赛

2815. 数组中的最大数对和 核心思想&#xff1a;维护每一个最大的数字的最大值&#xff0c;然后一边更新最大值&#xff0c;一边统计结果。其中求nums中的每一个数的数位最大值可以用map的方法&#xff0c;我自己做的时候是用的%10&#xff0c;感觉map这种方法很巧妙。 2816. …

【Linux】可重入函数 volatile关键字 以及SIGCHLD信号

可重入函数 volatile关键字 以及SIGCHLD信号 一、可重入函数1、引入2、可重入函数的判断 二、volatile关键字1、引入2、关于编译器的优化的简单讨论 三、SIGCHLD信号 一、可重入函数 1、引入 我们来先看一个例子来帮助我们理解什么是可重入函数&#xff1a; 假设我们现在要对…

微软电脑surface键盘无法使用问题解决

昨天下班后&#xff0c;正常关掉电脑&#xff0c;今天来上班发现键盘无法使用了 打人工找到了解决方法 开机->到锁屏页面->使用屏幕键盘输入密码进入电脑 然后右键左下角的win图标 找到设备管理器->键盘 全部右键卸载 再找到设备管理->系统设备 把这个DTX也卸…

母婴即时零售行业数据可视化分析

对新晋父母来说&#xff0c;很多母婴用品如同一位贴心的助手&#xff0c;为他们的宝宝提供温暖和呵护。从婴儿床垫到可爱的拼图玩具&#xff0c;每一件用品都是为宝宝的成长和发展量身定制。对于繁忙的父母们而言&#xff0c;这些用品不仅帮助照顾孩子&#xff0c;更是为他们减…

ISIS技术(第三十七课)

1 分享一下华为官网上的一张地图 官网地址:https://support.huawei.com/hedex/hdx.do?docid=EDOC1000105967&id=ZH-CN_CONCEPT_0000001501534705 2 路由的分类 -直连路由 直接连接的路由,且配置了IP地址之后(在同一网段内),就是直连路由。 -非直连路由 -静态路由…

奥威BI数据可视化工具:报表就是平台,随时自助分析

别的数据可视化工具&#xff0c;报表就只是报表&#xff0c;而奥威BI数据可视化工具&#xff0c;一张报表就约等于一个平台&#xff0c;可随时展开多维动态自助分析&#xff0c;按需分析&#xff0c;立得数据信息。 奥威BI是一款多维立体分析数据的数据可视化工具。它可以帮助…

Hadoop Hbase Hive 版本对照一览

这里写目录标题 一、Hadoop 与 Hbase 版本对照二、Hadoop 与 Hive 版本对照 官网内容记录&#xff0c;仅供参考 一、Hadoop 与 Hbase 版本对照 二、Hadoop 与 Hive 版本对照

10-1_Qt 5.9 C++开发指南_Data Visualization实现数据三维显示

Data Visualization 是 Qt 提供的用于数据三维显示的模块。在 Qt 5.7 以前只有商业版才有此模块&#xff0c;而从Qt5.7 开始此模块在社区版本里也可以免费使用了。Data Visualization 用于数据的三维显示&#xff0c;包括三维柱状图、三维空间散点、三维曲面等。Data Visualiza…

从零开始学极狐GitLab|03 Runner 裸机部署

目录 极狐GitLab SaaS 版&#xff08;无需部署&#xff09; 安装自己的极狐GitLab- Runner 1. macOS ➤ 安装 ➤ 注册 2. Linux ➤ 安装 ➤ 注册 3. Windows ➤ 安装 ➤ 注册 【从零开始学极狐GitLab】专栏由极狐GitLab 社区开发者“雪碧能喝多”投稿&#xff0c;面…

【excel技巧】Excel表格如何取消隐藏行?

Excel工作表中的行列隐藏了数据&#xff0c;如何取消隐藏行列呢&#xff1f;今天分享几个方法给大家 方法一&#xff1a; 选中隐藏的区域&#xff0c;点击右键&#xff0c;选择【取消隐藏】就可以了 方法二&#xff1a; 如果工作表中有多个地方有隐藏的话&#xff0c;还是建…

MongoDB常用命令

什么是MongoDB ? MongoDB 是由C语言编写的&#xff0c;是一个基于分布式文件存储的开源数据库系统。 在高负载的情况下&#xff0c;添加更多的节点&#xff0c;可以保证服务器性能。 MongoDB 旨在为WEB应用提供可扩展的高性能数据存储解决方案。 MongoDB 将数据存储为一个…

457. 环形数组是否存在循环

457. 环形数组是否存在循环 原题链接&#xff1a;完成情况&#xff1a;解题思路&#xff1a;参考代码&#xff1a;经验吸取 原题链接&#xff1a; 457. 环形数组是否存在循环 https://leetcode.cn/problems/circular-array-loop/description/ 完成情况&#xff1a; 解题思路…

HTML详解连载(7)

HTML详解连载&#xff08;7&#xff09; 专栏链接 [link](http://t.csdn.cn/xF0H3)下面进行专栏介绍 开始喽结构伪类选择器作用 :nth-child&#xff08;公式&#xff09;作用举例 伪元素选择器作用注意&#xff1a; PxCoook作用盒子模型-重要组成部分 盒子模型-边框线属性名属性…

win10中Docker安装、构建镜像、创建容器、Vscode连接实例

Docker方便一键构建项目所需的运行环境&#xff1a;首先构建镜像(Image)。然后镜像实例化成为容器(Container)&#xff0c;构成项目的运行环境。最后Vscode连接容器&#xff0c;方便我们在本地进行开发。下面以一个简单的例子介绍在win10中实现&#xff1a;Docker安装、构建镜像…

在 Linux 虚拟机上使用 Azure 自定义脚本扩展版本

参考 azure创建虚拟机,创建虚拟机注意入站端口规则开放80端口、 2.转到资源&#xff0c;点击扩展应用程序&#xff0c;创建存储账户&#xff0c;创建容器&#xff0c;上传文件&#xff0c;选择文件&#xff0c;会自动执行部署。 apt-get update -y && apt-get insta…

【Rust】Rust学习 第十二章一个 I/O 项目:构建一个命令行程序

本章既是一个目前所学的很多技能的概括&#xff0c;也是一个更多标准库功能的探索。我们将构建一个与文件和命令行输入/输出交互的命令行工具来练习现在一些你已经掌握的 Rust 技能。 Rust 的运行速度、安全性、单二进制文件输出和跨平台支持使其成为创建命令行程序的绝佳选择…

Failed to execute goal org.apache.maven.plugins

原因&#xff1a; 这个文件D:\java\maven\com\ruoyi\pg-student\maven-metadata-local.xml出了问题 解决&#xff1a; 最简单的直接删除D:\java\maven\com\ruoyi\pg-student\maven-metadata-local.xml重新打包 或者把D:\java\maven\com\ruoyi\pg-student这个目录下所有文件…