左神高级提升班1 很重要的题目

news2024/10/7 9:17:20

【案例1】

【题目描述 难度非常高】

 【思路解析】

因为要求额外空间复杂度为O(1),所以我们只能使用有限几个变量,来得到整个数组所在的城市距离首都的距离。因为数组paths[i]表示,i城市指向paths[i]城市,我们可以利用这个指向关系(next为下次要去的城市,last为当前城市。并且在往前遍历时,要记录回去的信息,即paths[next的值]=last的值,这样我们就可以再通过last和next往回走),一直往前遍历,直到next==paths[next],或者paths[next] < 0,我们便开始往回走,并且回走时,如果城市i距离首都为x,则给paths[i]赋值为-x。

然后得到了这个距离数组后,再通过判断距离数组的正负来统计距离(通过指向关系来进行循环计数)的个数。

【代码实现】

import java.util.Arrays;

/**
 * @ProjectName: study3
 * @FileName: Ex1
 * @author:HWJ
 * @Data: 2023/9/14 22:30
 */
public class Ex1 {
    public static void main(String[] args) {
        int[] paths = {9, 1, 4, 9, 0, 4, 8, 9, 0, 1};
        pathToDistance(paths);
        distanceToCount(paths);
        System.out.println(Arrays.toString(paths));
    }

    public static void pathToDistance(int[] paths) {
        int n = paths.length;
        int capital = -1;
        for (int start = 0; start < n; start++) {
            if (paths[start] == start) {
                capital = start;
            } else if (paths[start] > -1) {
                int last = start;
                int next = paths[last];
                while (paths[next] != next && paths[next] > -1) {
                        int num = paths[next];
                        paths[next] = last;
                        last = next;
                        next = num;
                }
                int i = paths[next] == next ? 0 : paths[next];
                while (last != start) {
                    int num = paths[last];
                    paths[last] = --i;
                    last = num;
                }
                paths[last] = --i;
            }
        }
        paths[capital] = 0;
    }

    public static void distanceToCount(int[] paths){
        for (int i = 0; i < paths.length; i++) {
            int cur = paths[i];
            paths[i] = Math.max(paths[i], 0);
            while (cur <= 0){
                int next = paths[-cur];
                if (next < 0){
                    paths[-cur] = 1;
                    cur = next;
                }else {
                    paths[-cur]++;
                    break;
                }
            }

        }
    }
}

【案例2】

【题目描述 分糖果问题】

一群孩子做游戏,现在请你根据游戏得分来发糖果,要求如下:

  1. 每个孩子不管得分多少,起码分到一个糖果。

  2. 任意两个相邻的孩子之间,得分较多的孩子必须拿多一些糖果。

  3. 【进价】要求相邻的两个孩子如果得分相同,得到的糖果应该相同。

  4. 要求时间复杂度为O(N)

【思路解析】

我们可以通过得分数组得到一个得分的折线图(即升降情况),然后通过从左向右遍历这个升降情况得到每个人应该分到的糖果数。然后通过从右向左遍历这个升降情况得到每个人应该分到的糖果数。然后对应求最大即为每个孩子的糖果数。遍历时要求升序糖果数++,如果降序或者保持不变,使糖果数变回1.

【进价思路分析】

我们可以通过得分数组得到一个得分的折线图(即升降情况),然后通过从左向右遍历这个升降情况得到每个人应该分到的糖果数。然后通过从右向左遍历这个升降情况得到每个人应该分到的糖果数。然后对应求最大即为每个孩子的糖果数。遍历时要求升序糖果数++,如果降序使糖果数变回1,如果保持不变,则使糖果数保持不变。

【代码实现】

/**
 * @ProjectName: study3
 * @FileName: Ex2
 * @author:HWJ
 * @Data: 2023/9/15 0:07
 */
public class Ex2 {
    public static void main(String[] args) {
        int[] scores = {1, 2, 2};
        System.out.println(candy1(scores));
        System.out.println(candy2(scores));
    }

    public static int candy1(int[] scores){
        int[] left = new int[scores.length];
        int[] right = new int[scores.length];
        left[0] = 1;
        for (int i = 1; i < scores.length; i++) {
            if(scores[i] > scores[i - 1]){
                left[i] = left[i - 1] + 1;
            }else {
                left[i] = 1;
            }
        }
        right[scores.length - 1] = 1;
        for (int i = scores.length - 2; i >= 1; i--) {
            if(scores[i] > scores[i + 1]){
                right[i] = right[i + 1] + 1;
            }else {
                right[i] = 1;
            }
        }
        int res = 0;
        for (int i = 0; i < scores.length; i++) {
            res += Math.max(left[i], right[i]);
        }
        return res;
    }

    public static int candy2(int[] scores){
        int[] left = new int[scores.length];
        int[] right = new int[scores.length];
        left[0] = 1;
        for (int i = 1; i < scores.length; i++) {
            if(scores[i] > scores[i - 1]){
                left[i] = left[i - 1] + 1;
            }else if (scores[i] < scores[i - 1]){
                left[i] = 1;
            }else {
                left[i] = left[i - 1];
            }
        }
        right[scores.length - 1] = 1;
        for (int i = scores.length - 2; i >= 1; i--) {
            if(scores[i] > scores[i + 1]){
                right[i] = right[i + 1] + 1;
            }else if (scores[i] < scores[i + 1]){
                right[i] = 1;
            }else {
                right[i] = right[i + 1];
            }
        }
        int res = 0;
        for (int i = 0; i < scores.length; i++) {
            res += Math.max(left[i], right[i]);
        }
        return res;
    }
}

【超级进阶   非常难】

要求时间复杂度为O(N), 额外空间复杂度为O(1)。   实现特别困难。

【案例3】

【题目描述】

【思路解析】二叉树递归套路类题目

第一种思路,列出所有可能性,然后在递归时得到所有可能性,然后不断汇总求最优解。

能获得最优解的可能性如下:

(1)x结点以下都被照亮(包含x结点),且x上不放灯。

(2)x结点以下都被照亮(包含x结点),且x上放灯。

(3)x结点以下都被照亮(不包含x结点),但x上放灯。(因为这种情况可能引出下一个最优解,在x的父上放灯,影响的结点更多)。

第二种思路,我们在传递的时候已知最优解需要的是什么信息,利用贪心加速常数时间。

比如当左孩子和右孩子,未被覆盖时,x上必须放灯,如果左孩子和右孩子,被覆盖且放灯,则x上一定不放灯。如果左孩子和右子,被覆盖但没放灯,则x未被覆盖。

【代码实现】 

/**
 * @ProjectName: study3
 * @FileName: Ex3
 * @author:HWJ
 * @Data: 2023/9/15 0:16
 */
public class Ex3 {
    public static void main(String[] args) {

    }

    public static class Node{
        Node left;
        Node right;
    }

    public static class ReturnData{
        public int unCovered;
        public int coveredNoCamera;
        public int coveredHasCamera;

        public ReturnData(int unCovered, int coveredNoCamera, int coveredHasCamera) {
            this.unCovered = unCovered;
            this.coveredNoCamera = coveredNoCamera;
            this.coveredHasCamera = coveredHasCamera;
        }
    }

    public static int getMin(Node head){
        ReturnData data = process(head);
        return Math.min(data.unCovered, Math.min(data.coveredHasCamera, data.coveredNoCamera));
    }

    public static ReturnData process(Node node){
        if (node == null){
            return new ReturnData(Integer.MAX_VALUE, 0, Integer.MAX_VALUE);
        }
        ReturnData left = process(node.left);
        ReturnData right = process(node.right);
        int unCovered = left.coveredNoCamera + right.coveredNoCamera;
        int coveredNoCamera = Math.min(left.coveredHasCamera + right.coveredHasCamera,
                Math.min(left.coveredHasCamera + right.coveredNoCamera,
                        left.coveredNoCamera + right.coveredHasCamera));
        int coveredHasCamera = Math.min(left.unCovered,
                Math.min(left.coveredHasCamera, left.coveredNoCamera)) +
                Math.min(right.unCovered,
                        Math.min(right.coveredHasCamera, right.coveredNoCamera)) + 1;
        return new ReturnData(unCovered, coveredNoCamera, coveredHasCamera);
    }

    public enum Status{
        UNCOVERED, COVERED_NO_CAMERA, COVERED_HAS_CAMERA;
    }

    public static class ReturnData2{
        public Status status;
        public int cameras;

        public ReturnData2(Status status, int cameras) {
            this.status = status;
            this.cameras = cameras;
        }
    }

    public static int getMin2(Node head){
        ReturnData2 data = process2(head);
        return data.cameras + (data.status == Status.UNCOVERED ? 1 : 0);
    }

    public static ReturnData2 process2(Node node){
        if (node == null){
            return new ReturnData2(Status.COVERED_NO_CAMERA, 0);
        }
        ReturnData2 left = process2(node.left);
        ReturnData2 right = process2(node.right);
        int cameras = left.cameras + right.cameras;
        if (left.status == Status.UNCOVERED || right.status == Status.UNCOVERED){
            return new ReturnData2(Status.COVERED_HAS_CAMERA, cameras + 1);
        }
        if (left.status == Status.COVERED_HAS_CAMERA && right.status == Status.COVERED_HAS_CAMERA){
            return new ReturnData2(Status.COVERED_NO_CAMERA, cameras);
        }
        return new ReturnData2(Status.UNCOVERED, cameras);
    }
}

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

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

相关文章

ElasticSearch系列-简介与安装详解

全文检索 讲ElasticSearch之前, 需要先提一下全文检索.全文检索是计算机程序通过扫描文章中的每一个词&#xff0c;对每一个词建立一个索引&#xff0c;指明该词在文章中出现的次数和位置。当用户查询时根据建立的索引查找&#xff0c;类似于通过字典的检索字表查字的过程。 …

内网隧道代理技术(二十六)之 搭建ICMP隧道上线CS

搭建ICMP隧道上线CS ICMP隧道原理 ICMP隧道简单实用,是一个比较特殊的协议。在一般的通信协议里,如果两台设备要进行通信,肯定需要开放端口,而在ICMP协议下就不需要。最常见的ping命令就是利用的ICMP协议,攻击者可以利用命令行得到比回复更多的ICMP请求。在通常情况下,…

Django系列:Django的项目结构与配置解析

Django系列 Django的项目结构与配置解析 作者&#xff1a;李俊才 &#xff08;jcLee95&#xff09;&#xff1a;https://blog.csdn.net/qq_28550263 邮箱 &#xff1a;291148484163.com 本文地址&#xff1a;https://blog.csdn.net/qq_28550263/article/details/132893616 【介…

参议员和科技巨头的私人人工智能峰会引发争议

周三&#xff0c;美国参议员查克舒默(D-NY)在参议院办公楼举办了一场关于潜在人工智能监管的“人工智能洞察论坛”。与会者包括亿万富翁和现代行业巨头&#xff0c;如埃隆马斯克、比尔盖茨、马克扎克伯格、OpenAI的萨姆奥特曼和英伟达的黄仁勋。但是这份公司客人名单22个中的14…

晨控CK-FR102系列与汇川AC800系列MODBUSTCP通讯手册

晨控CK-FR102系列与汇川AC800系列MODBUSTCP通讯手册 晨控CK-FR102AN系列是一款基于射频识别技术的高频双通道读写器&#xff0c;读写器工作频率为13.56MHZ&#xff0c;支持对I-CODE 2、I-CODE SLI等符合ISO15693国际标准协议格式标签的读取。高频双通道读写器支持标准工业通讯…

在PG或HGDB上启用块校验checksum

瀚高数据库 目录 环境 文档用途 详细信息 环境 系统平台&#xff1a;Linux x86-64 Red Hat Enterprise Linux 7 版本&#xff1a;14,N/A 文档用途 用途 使用checksum&#xff0c;对数据库提供块校验&#xff0c;以发现隐藏的块损坏问题&#xff0c;注意仅适用于原生PG或…

PHP自己的框架2.0设置常量并绑定容器(重构篇三)

目录 1、设置常量并绑定容器 2、容器增加设置当前容器的实例和绑定一个类实例当容器 3、将常量绑定到容器中 4、运行效果 1、设置常量并绑定容器 2、容器增加设置当前容器的实例和绑定一个类实例当容器 //设置当前容器的实例public static function setInstance($instance){…

深度学习-全连接神经网络-训练过程-批归一化- [北邮鲁鹏]

文章目录 思想批归一化操作批归一化与梯度消失经过BN处理 算法实现 思想 直接对神经元的输出进行批归一化 批归一化&#xff1a;对输出值进行归一化&#xff0c;将归一化结果平移缩放作为输出。 批归一化操作 小批量梯度下降算法回顾&#xff1a;每次迭代时会读入一批数据&am…

数据分享|R语言因子分析、相关性分析大学生兼职现状调查问卷数据可视化报告...

全文链接&#xff1a;http://tecdat.cn/?p31765 随着大学的普及教育&#xff0c;大学生就业形势变得更加困难&#xff0c;很多学生都意识到这个问题&#xff08;点击文末“阅读原文”获取完整代码数据&#xff09;。 相关视频 所以走出象牙塔&#xff0c;去接触社会&#xff0…

Mybatis逆向生成代码

编写mybatis generator配置 1、在resources目录下编写配置 内容如下&#xff0c;根据自己需要改动包名、密码等信息&#xff1a; <?xml version"1.0" encoding"UTF-8" ?> <!DOCTYPE generatorConfiguration PUBLIC "-//mybatis.org//DTD…

【linux基础(六)】Linux中的开发工具(中)--gcc/g++

&#x1f493;博主CSDN主页:杭电码农-NEO&#x1f493;   ⏩专栏分类:Linux从入门到开通⏪   &#x1f69a;代码仓库:NEO的学习日记&#x1f69a;   &#x1f339;关注我&#x1faf5;带你学更多操作系统知识   &#x1f51d;&#x1f51d; Linux中的开发工具 1. 前言2.…

Spring Boot通过lombok提供的Slf4j省略日志的创建操作

上文 Spring Boot将声明日志步骤抽离出来做一个复用类中 我们写了个创建日志的公开类 但这么简单的东西 自然有人会将它写好 lombok已经 提供出了这个工具 首先 我们需要在 pom.xml 中加上这样一段代码 <dependency><groupId>org.projectlombok</groupId>…

【JavaEE】多线程案例-阻塞队列

1. 前言 阻塞队列&#xff08;BlockingQueue&#xff09;是一个支持两个附加操作的队列。这两个附加的操作是&#xff1a; 在队列为空时&#xff0c;获取元素的线程会等待队列变为非空当队列满时&#xff0c;存储元素的线程会等待队列可用 阻塞队列常用于生产者和消费者的场…

SQlite操作后如何正确退出

在 C 语言中&#xff0c;使用 SQLite 库进行数据库操作后&#xff0c;可以通过以下步骤来正常退出和关闭 SQLite 连接&#xff1a; 关闭数据库连接&#xff1a;在完成数据库操作后&#xff0c;使用 sqlite3_close() 函数来关闭 SQLite 连接。该函数接受一个指向 sqlite3 数据库…

跨域问题解决方案(三种)

Same Origin Policy同源策略&#xff08;SOP&#xff09; 具有相同的Origin&#xff0c;也即是拥有相同的协议、主机地址以及端口。一旦这三项数据中有一项不同&#xff0c;那么该资源就将被认为是从不同的Origin得来的&#xff0c;进而不被允许访问。 Cross-origin resource…

Qt/C++音视频开发53-本地摄像头推流/桌面推流/文件推流/监控推流等

一、前言 编写这个推流程序&#xff0c;最开始设计的时候是用视频文件推流&#xff0c;后面陆续增加了监控摄像头推流&#xff08;其实就是rtsp视频流&#xff09;、网络电台和视频推流&#xff08;一般是rtmp或者http开头m3u8结尾的视频流&#xff09;、本地摄像头推流&#…

ArcGIS 10.2安装教程!

软件介绍&#xff1a;ArcGIS是一款专业的电子地图信息编辑和开发软件&#xff0c;提供一种快速并且使用简单的方式浏览地理信息&#xff0c;无论是2D还是3D的信息。软件内置多种编辑工具&#xff0c;可以轻松的完成地图生产全过程&#xff0c;为地图分析和处理提供了新的解决方…

【LeetCode75】第五十六题 爱吃香蕉的珂珂

目录 题目&#xff1a; 示例&#xff1a; 分析&#xff1a; 代码&#xff1a; 题目&#xff1a; 示例&#xff1a; 分析&#xff1a; 这道题挺炸裂的&#xff0c;题目给我们一个数组&#xff0c;数组里的每个元素表示每个仓库里的香蕉数量。 珂珂可以自己控制自己吃香蕉的…

头条移动端项目Day08 —— 定时计算热点文章、XXL-JOB

❤ 作者主页&#xff1a;欢迎来到我的技术博客&#x1f60e; ❀ 个人介绍&#xff1a;大家好&#xff0c;本人热衷于Java后端开发&#xff0c;欢迎来交流学习哦&#xff01;(&#xffe3;▽&#xffe3;)~* &#x1f34a; 如果文章对您有帮助&#xff0c;记得关注、点赞、收藏、…

算法——快乐数

202. 快乐数 - 力扣&#xff08;LeetCode&#xff09; 由图可知&#xff0c;其实这也是一个判断循环的过程&#xff0c;要用到快慢指针&#xff0c;且相遇后&#xff0c;若在全为1的循环里&#xff0c;那么就是快乐数&#xff0c;若相遇后不为1&#xff0c;说明这不是快乐数。 …