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 ...
随机推荐
- VSCODE C# 运行 找不到任务"BUILD"----C#常用命令
使用 Visual Studio Code 创建 .NET 类库 - .NET | Microsoft Docs 安装vscode.vscode c#相关拓展.MINIGW64 1.创建文件夹 2.用 ...
- Postgresql 或GreenPlum 查询结果部分字段转json格式并保留字段名(row_to_json)
-- 一些搜索结果给出 部分字段转json保留原字段的方式是用子查询select row_to_json(t) from ( select id, text from words ) t 但是如果子查 ...
- Log4j日志框架使用
Log4j是Apache下的一款开源的日志框架,能够满足我们在项目中对于日志记录的需求.一般来讲,在项目中,我们会结合slf4j和log4j一起使用.Log4j提供了简单的API调用,强大的日志格式定 ...
- 信创国产化,试试 Solon v2.2.2
Solon 是一个高效的 Java 应用开发框架:更快.更小.更简单.它不是 Spring.没有用 Servlet.也无关 JavaEE,是一个有自己接口标准的开放生态.可以为应用软件国产化提供支持, ...
- Spring设计模式——代理模式[手写实现JDK动态代理]
代理模式 代理模式(Proxy Pattern):是指为其他对象提供一种代理,以控制对这个对象的访问. 代理对象在客户端和目标对象之间起到中介作用,代理模式属于结构型设计模式. 使用代理模式主要有两个 ...
- c/c++指针从浅入深介绍——基于数据内存分配的理解(上)
c/c++指针从浅入深介绍--基于数据内存分配的理解(上) 本文是对自我学习的一个总结以及回顾,文章内容主要是针对代码中的数据在内存中的存储情况以及存储中数值的变化来对指针进行介绍,是对指针以及数据在 ...
- 如何基于 React Native 快速实现一个视频通话应用
今天,我们将会一起开发一个包含 RTE (实时互动)场景的 Flutter 应用. 项目介绍 靠自研开发包含实时互动功能的应用非常繁琐,你要解决维护服务器.负载均衡等难题,同时还要保证稳定的低延迟. ...
- Maven安装详解
Maven Maven是apache软件基金会旗下的一个开源项目,是一款用于管理和构建Java项目的工具. Maven的作用? 先来简单介绍一下Maven的作用 (1)依赖管理 方便快捷的管理项目依赖 ...
- 自己动手从零写桌面操作系统GrapeOS系列教程——20.汇编语言读硬盘实战
学习操作系统原理最好的方法是自己写一个简单的操作系统. 本讲我们设计一个简单的读硬盘实验.通过一定的方法使硬盘第二个扇区的前3个字节依次为1.2.3,最后3个字节依次为3.2.1,中间的506个字节全 ...
- 统计数据异常值的处理——R语言
在数据分析工作中,面对收集而来的数据,数据清洗是首要环节.异常值(outlier)是数据清洗的重要环节,异常值可能直接会导致后面的数据分析.建模工作出现偏差,下面就给大家介绍一下如何处理数据中的异常值 ...