【C#算法实现】可见的山峰对数量

文章目录

  • 前言
  • 一、题目要求
  • 二、算法设计及代码实现
    • 2.1 算法思想
    • 2.2 代码实现

前言

本文是【程序员代码面试指南(第二版)学习笔记】C#版算法实现系列之一,用C#实现了《程序员代码面试指南》(第二版)栈和队列中的可见的山峰对数量。文中的示意图也都来自此书。


一、题目要求

给出一个全为正整数的循环数组,每一个数字表示一个山峰的高度,找出一共有几对山峰可以相互看到。
相互看到的条件:如果两座山峰之间不管是顺序看也好逆序看也罢,只要有一个方向可以达到两座山峰之间的山的高度都小于两座山峰的要求,那么就说明相互可以看到。
示例
如图,最下方的5可以和左边的3相互看到,因为中间的2 < 3且2 < 5。最下面的5和最右边的5也是相互可见的,虽然顺时针方向有一个5不小于5,但是逆时针方向中间只有4和3,是满足要求的,所以互相可见。

二、算法设计及代码实现

2.1 算法思想

概述:首先要确定一点,假如A能看到B,那么其实计算过程中如果还计算B能看到A就重复了。而又因为低山峰找高山峰较为方便,这里确定为小找大。确定为小找大后,就可以定义一个单调递增的栈,保证栈内元素始终为栈顶到栈底依次增大。如果遇到相同大小的元素,那么只需要在该元素位置记录次数加一即可。首先将栈底放入最大值,随后遍历数组。遇到不符合单调性的元素入栈时,说明栈顶元素找到了前进方向的比自己高的山了,由于栈底肯定大于栈顶,也就说明栈顶两端都满足小找大的条件了,不可能找到更多对的山峰了,这时就可以出栈计算结果了。遍历结束一遍后,还会有剩余元素,这时依旧按照小找大规则进行出栈计算即可。

详细步骤
1、定义一个记录值和出现次数的结构体,这里选择用类是因为结构体是值类型,修改不如引用类型方便。
2、初始化一个栈和记录结果的变量。
3、找出最大值和最大值所在的序列作为遍历的起点。
4、循环遍历一遍数组,遍历每个元素都做以下操作:
1)栈空直接放入元素。
2)栈顶小于当前要放入的元素,那么就出栈,出栈累加结果,此时找到的山峰对数为2 * times + times * (times - 1) / 2。
3)如果相等,则直接累加出现次数。
4)符合单调性,则直接放入。
5、遍历结束后还有剩余元素,此时分为三个阶段:
1)如果剩余元素大于等于三个,逐个出栈,直到剩下2个为止。出栈时,累加结果公式为2 * times + times * (times - 1) / 2。
2)倒数第二个元素的出栈:记最后一个元素的重复次数为lt,那么累加结果公式为times * (lt > 1 ? 2 : 1) + times * (times - 1) / 2
3)最后一个元素的出栈公式为times * (times - 1) / 2。

2.2 代码实现

public class Record(int value, int times) {public int value = value;public int times = times;
}public static int GetVisibleNum(int[] arr) {int n = arr.Length;Stack<Record> stack = new();int ans = 0;// 找出最大值和位置int max = 0;int maxIndex = -1;for (int i = 0; i < n; i++) {if (arr[i] > max) {max = arr[i];maxIndex = i;}}// 从最大值的位置开始遍历for (int i = maxIndex; i < n + maxIndex; i++) {int index = i % n;int value = arr[index];// 如果栈为空, 直接入栈if (stack.Count == 0) {stack.Push(new Record(value, 1));continue;}// 栈顶元素小于当前元素, 则出栈while (stack.Peek().value < value) {Record record = stack.Pop();ans += record.times * 2 + record.times * (record.times - 1) / 2;}// 栈顶元素等于当前元素, 则更新栈顶元素的次数if (stack.Peek().value == value) {Record record = stack.Peek();record.times++;}// 栈顶元素大于当前元素, 则入栈else {stack.Push(new Record(value, 1));}}// 栈中剩余元素while (stack.Count > 2) {Record record = stack.Pop();ans += record.times * 2 + record.times * (record.times - 1) / 2;}if (stack.Count == 2) {Record record = stack.Pop();Record last = stack.Peek();ans += record.times * (last.times > 1 ? 2 : 1) + record.times * (record.times - 1) / 2;}if (stack.Count == 1) {Record record = stack.Pop();ans += record.times * (record.times - 1) / 2;}return ans;
}

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

多线程(代码案例: 单例模式, 阻塞队列, 生产者消费者模型,定时器)

设计模式是什么 类似于棋谱一样的东西 计算机圈子里的大佬为了能让小菜鸡的代码不要写的太差 针对一些典型的场景, 给出了一些典型的解决方案 这样小菜鸡们可以根据这些方案(ACM里面叫板子, 象棋五子棋里叫棋谱, 咱这里叫 设计模式), 略加修改, 这样代码再差也差不到哪里去 … …

python基于flask共享单车管理系统 234if

快速发展的社会中&#xff0c;人们的生活水平都在提高&#xff0c;生活节奏也在逐渐加快。为了节省时间和提高工作效率&#xff0c;越来越多的人选择利用互联网进行线上打理各种事务&#xff0c;然后线上管理系统也就相继涌现。与此同时&#xff0c;人们开始接受方便的生活方式…

FFmepg--音频编码流程--pcm编码为aac

文章目录 基本概念流程apicode(核心部分) 基本概念 从本地⽂件读取PCM数据进⾏AAC格式编码&#xff0c;然后将编码后的AAC数据存储到本地⽂件。 PCM样本格式&#xff1a;未经压缩的⾳频采样数据裸流 参数&#xff1a; Sample Rate : 采样频率Sample Size : 量化位数Number o…

ASP.NET Core 8.0 WebApi 从零开始学习JWT登录认证

文章目录 前言相关链接Nuget选择知识补充JWT不是加密算法可逆加密和不可逆加密 普通Jwt&#xff08;不推荐&#xff09;项目环境Nuget 最小JWT测试在WebApi中简单使用简单使用运行结果 WebApi 授权&#xff0c;博客太老了&#xff0c;尝试失败 WebApi .net core 8.0 最新版Jwt …

unity报错出现Asset database transaction committed twice!

错误描述&#xff1a; 运行时报错 Assertion failed on expression: ‘m_ErrorCode MDB_MAP_RESIZED || !HasAbortingErrors()’Asset database transaction committed twice!Assertion failed on expression: ‘errors MDB_SUCCESS || errors MDB_NOTFOUND’ 解决办法&…

【iOS】ARC学习

文章目录 前言一、autorelease实现二、苹果的实现三、内存管理的思考方式__strong修饰符取得非自己生成并持有的对象__strong 修饰符的变量之间可以相互赋值类的成员变量也可以使用strong修饰 __weak修饰符循环引用 __unsafe_unretained修饰符什么时候使用__unsafe_unretained …

蓝桥杯前端Web赛道-输入搜索联想

蓝桥杯前端Web赛道-输入搜索联想 题目链接&#xff1a;1.输入搜索联想 - 蓝桥云课 (lanqiao.cn) 题目要求&#xff1a; 题目中还包含effect.gif 更详细的说明了需求 那么观察这道题需要做两件事情 把表头的每一个字母进行大写进行模糊查询 这里我们会用到几个js函数&#…

Python引入其他文件作为包

1.首先当我们写的代码&#xff0c;可能要被其他文件引用&#xff0c;那么在建文件夹的时候&#xff0c;记得选包 不是文件夹&#xff01;&#xff08;选第4个&#xff0c;不是第3个&#xff09; 因为文件夹默认没有init 方法&#xff0c;不能导包... 如果已经是文件夹了&#…

ChatGPT赋能遥感研究:精准分析处理遥感影像数据,推动科研新突破

遥感技术主要通过卫星和飞机从远处观察和测量我们的环境&#xff0c;是理解和监测地球物理、化学和生物系统的基石。ChatGPT是由OpenAI开发的最先进的语言模型&#xff0c;在理解和生成人类语言方面表现出了非凡的能力。重点介绍ChatGPT在遥感中的应用&#xff0c;人工智能在解…

python flask服务如何注册到nacos

shigen坚持更新文章的博客写手&#xff0c;擅长Java、python、vue、shell等编程语言和各种应用程序、脚本的开发。记录成长&#xff0c;分享认知&#xff0c;留住感动。 个人IP&#xff1a;shigen 背景 shigen之前遇到了一个服务&#xff0c;需要结合nacos Spring security实现…

Ps 滤镜:中间值

Ps菜单&#xff1a;滤镜/杂色/中间值 Filter/Noise/Median 中间值 Median滤镜可用于减少或消除图像中的噪点和杂色&#xff0c;同时能较好地保留图像边缘和细节信息。 中间值滤镜通过计算一个像素周围一定区域内的像素值的中间值&#xff08;即这些值的中位数&#xff09;&…

叶顺舟:手机SoC音频趋势洞察与端侧AI技术探讨 | 演讲嘉宾公布

后续将陆续揭秘更多演讲嘉宾&#xff01; 请持续关注&#xff01; 2024中国国际音频产业大会(GAS)将于2024年3.27 - 28日在上海张江科学会堂举办。大会将以“音无界&#xff0c;未来&#xff08;Audio&#xff0c; Future&#xff09;”为主题。大会由中国电子音响行业协会、上…