2021-07-17:一个不含有负数的数组可以代表一圈环形山,每个位置的值代表山的高度。比如, {3,1,2,4,5}、{4,5,3,1,2}或{1,2,4,5,3}都代表同样结构的环形山。山峰A和山
2021-07-17:一个不含有负数的数组可以代表一圈环形山,每个位置的值代表山的高度。比如, {3,1,2,4,5}、{4,5,3,1,2}或{1,2,4,5,3}都代表同样结构的环形山。山峰A和山峰B能够相互看见的条件为: 1.如果A和B是同一座山,认为不能相互看见,2.如果A和B是不同的山,并且在环中相邻,认为可以相互看见,3.如果A和B是不同的山,并且在环中不相邻,假设两座山高度的最小值为min,1)如果A通过顺时针方向到B的途中没有高度比min大的山峰,认为A和B可以相互看见,2)如果A通过逆时针方向到B的途中没有高度比min大的山峰,认为A和B可以相互看见。两个方向只要有一个能看见,就算A和B可以相互看见。给定一个不含有负数且没有重复值的数组 arr,请返回有多少对山峰能够相互看见。进阶问题:给定一个不含有负数但可能含有重复值的数组arr,返回有多少对山峰能够相互看见。
福大大 答案2021-07-17:
时间紧,见代码。
代码用golang编写。代码如下:
package main
import (
"container/list"
"fmt"
)
func main() {
arr := []int{3, 1, 2, 4, 5, 3, 1, 2, 4, 5}
ret := getVisibleNum(arr)
fmt.Println(ret)
}
// 栈中放的记录,
// value就是指,times是收集的个数
type Record struct {
value int
times int
}
func NewRecord(value int) *Record {
ret := &Record{}
ret.value = value
ret.times = 1
return ret
}
func twoSelectOne(c bool, a int, b int) int {
if c {
return a
} else {
return b
}
}
func getVisibleNum(arr []int) int {
if len(arr) < 2 {
return 0
}
N := len(arr)
maxIndex := 0
// 先在环中找到其中一个最大值的位置,哪一个都行
for i := 0; i < N; i++ {
maxIndex = twoSelectOne(arr[maxIndex] < arr[i], i, maxIndex)
}
stack := list.New().Init()
// 先把(最大值,1)这个记录放入stack中
stack.PushBack(NewRecord(arr[maxIndex]))
// 从最大值位置的下一个位置开始沿next方向遍历
index := nextIndex(maxIndex, N)
// 用“小找大”的方式统计所有可见山峰对
res := 0
// 遍历阶段开始,当index再次回到maxIndex的时候,说明转了一圈,遍历阶段就结束
for index != maxIndex {
// 当前数要进入栈,判断会不会破坏第一维的数字从顶到底依次变大
// 如果破坏了,就依次弹出栈顶记录,并计算山峰对数量
for stack.Back().Value.(*Record).value < arr[index] {
k := stack.Back().Value.(*Record).times
stack.Remove(stack.Back())
// 弹出记录为(X,K),如果K==1,产生2对; 如果K>1,产生2*K + C(2,K)对。
res += getInternalSum(k) + 2*k
}
// 当前数字arr[index]要进入栈了,如果和当前栈顶数字一样就合并
// 不一样就把记录(arr[index],1)放入栈中
if stack.Back().Value.(*Record).value == arr[index] {
stack.Back().Value.(*Record).times++
} else { // >
stack.PushBack(NewRecord(arr[index]))
}
index = nextIndex(index, N)
}
// 清算阶段开始了
// 清算阶段的第1小阶段
for stack.Len() > 2 {
times := stack.Back().Value.(*Record).times
stack.Remove(stack.Back())
res += getInternalSum(times) + 2*times
}
// 清算阶段的第2小阶段
if stack.Len() == 2 {
times := stack.Back().Value.(*Record).times
stack.Remove(stack.Back())
res += getInternalSum(times) + twoSelectOne(stack.Back().Value.(*Record).times == 1, times, 2*times)
}
// 清算阶段的第3小阶段
res += getInternalSum(stack.Back().Value.(*Record).times)
stack.Remove(stack.Back())
return res
}
// 如果k==1返回0,如果k>1返回C(2,k)
func getInternalSum(k int) int {
return twoSelectOne(k == 1, 0, k*(k-1)/2)
}
// 环形数组中当前位置为i,数组长度为size,返回i的下一个位置
func nextIndex(i int, size int) int {
return twoSelectOne(i < (size-1), i+1, 0)
}
执行结果如下:

2021-07-17:一个不含有负数的数组可以代表一圈环形山,每个位置的值代表山的高度。比如, {3,1,2,4,5}、{4,5,3,1,2}或{1,2,4,5,3}都代表同样结构的环形山。山峰A和山的更多相关文章
- 2021.07.17 题解 CF1385E Directing Edges(拓扑排序)
2021.07.17 题解 CF1385E Directing Edges(拓扑排序) CF1385E Directing Edges - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) ...
- 2021.07.17 P4170 染色(区间DP)
2021.07.17 P4170 染色(区间DP) [P4170 CQOI2007]涂色 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 重点: 1.目标状态可以由哪些状态转移过来. ...
- 2021.07.17 P3177 树上染色(树形DP)
2021.07.17 P3177 树上染色(树形DP) [P3177 HAOI2015]树上染色 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 重点: 1.dp思想是需要什么,维护 ...
- 2021.07.09 K-D树
2021.07.09 K-D树 前置知识 1.二叉搜索树 2.总是很长的替罪羊树 K-D树 建树 K-D树具有二叉搜索树的形态,对于每一个分类标准,小于标准的节点在父节点左边,大于标准的节点在父节点右 ...
- 2021.07.23 P2474 天平(差分约束)
2021.07.23 P2474 天平(差分约束) [P2474 SCOI2008]天平 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 题意: 已知A,B和每两个点点权,求点权i, ...
- 2021.07.19 P2294 狡猾的商人(差分约束)
2021.07.19 P2294 狡猾的商人(差分约束) [P2294 HNOI2005]狡猾的商人 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 重点: 1.差分约束最长路与最短 ...
- 2021.07.26 P1022 计算器的改良(字符串)
2021.07.26 P1022 计算器的改良(字符串) 改进: 如果是我出题,我一定把未知数设为ab.buh.bluesky之类的长度不只是1的字符串! 题意: 一个一元一次方程,求解. 分析: 1 ...
- 2021.07.23 P3275 糖果(差分约束)
2021.07.23 P3275 糖果(差分约束) [P3275 SCOI2011]糖果 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 重点: 1.为了满足更多更多约束条件,合适地 ...
- 2021.07.19 BZOJ2654 tree(生成树)
2021.07.19 BZOJ2654 tree(生成树) tree - 黑暗爆炸 2654 - Virtual Judge (vjudge.net) 重点: 1.生成树的本质 2.二分 题意: 有一 ...
- 面试题:给定一个长度为N的数组,其中每个元素的取值范围都是1到N。判断数组中是否有重复的数字
题目:给定一个长度为N的数组,其中每个元素的取值范围都是1到N.判断数组中是否有重复的数字.(原数组不必保留) 方法1.对数组进行排序(快速,堆),然后比较相邻的元素是否相同.时间复杂度为O(nlog ...
随机推荐
- Repeater 绑定数据如何根据数据列的内容排序
可指定Repeater的数据源 从数据库查询时直接排序,而后绑定数据这样
- 第二章启动引导器GRUB2
第二章启动引导器GRUB2grub的配置文件路径:vim /boot/grub2/grub.cfg (不建议直接编辑)vim /etc/default/grub (可编辑的文件)将编辑的操作刷新到/b ...
- luffy前端配置and跨域
1. 安装axios 命令:npm install axios main.js内配置并使用 import axios from 'axios'app.config.globalProperties.$ ...
- c++中文编码格式
c++程序中涉及到中文字符的输入输出以及其他操作经常会出现乱码.乱码主要是由于程序的源文件编码.可执行文件编码以及程序运行环境的编码不匹配导致.比如,c++源程序文件编码为GB18030, 在源程序中 ...
- 【建造者设计模式详解】Java/JS/Go/Python/TS不同语言实现
简介 建造者模式(Builder Pattern),也叫生成器模式,属于创建型模式.它使用多个简单的对象一步一步构建成一个复杂的对象.它允许你使用相同的创建代码生成不同类型和形式的对象. 当你希望使用 ...
- 如何规避MyBatis使用过程中带来的全表更新风险
作者:京东零售 贾玉西 一.前言 程序员A: MyBatis用过吧? 程序员B: 用过 程序员A: 好巧,我也用过,那你遇到过什么风险没?比如全表数据被更新或者删除了. 程序员B: 咔,还没遇到过,这 ...
- Maven学习笔记1:Maven基本介绍和安装配置
一.认识Maven 官网 http://maven.apache.org/ 上面有最权威的说明,其中包括下载.安装.运行示例,但是是英文版的. Maven是什么 Maven是一个项目管理工具. 它有何 ...
- Goravel ORM 新增模型关联,用 Golang 写关联也可以跟 Laravel 一样简单
关于 Goravel Goravel 是一个功能完备.具有良好扩展能力的 Web 应用程序框架.作为一个起始脚手架帮助 Golang 开发者快速构建自己的应用.框架风格与 Laravel 保持一致,让 ...
- IDEA配置JDK版本的地方, 适用于Compilation failed: internal java compiler error
错误原因: 1. 编译版本不匹配 2.当前项目jdk版本不支持 解决方法 查看项目的jdk 查看工程的jdk 查看java编译器版本 讲这些改成自己需要的版本, 一般就可以解决编译版本出现的错误
- MyBatis 版本升级引发的线上问题
MyBatis上线前后的版本:上线前(3.2.3)上线后(3.4.6) 服务上线后,开始陆续出现了一些更新系统交互日志方面的报警,这属于系统的辅助流程,报警如下代码所示.我们发现都是跟 MyBatis ...