2022-01-12:给定一个正数数组arr,长度为n,下标0~n-1, arr中的0、n-1位置不需要达标,它们分别是最左、最右的位置, 中间位置i需要达标,达标的条件是 : arr[i-1] >
2022-01-12:给定一个正数数组arr,长度为n,下标0~n-1,
arr中的0、n-1位置不需要达标,它们分别是最左、最右的位置,
中间位置i需要达标,达标的条件是 : arr[i-1] > arr[i] 或者 arr[i+1] > arr[i]哪个都可以。
你每一步可以进行如下操作:对任何位置的数让其-1,
你的目的是让arr[1~n-2]都达标,这时arr称之为yeah!数组。
返回至少要多少步可以让arr变成yeah!数组。
数据规模 : 数组长度 <= 10000,数组中的值<=500。
来自360面试。
答案2022-01-12:
方法一、动态规划。
方法二、贪心。
时间复杂度:O(N)。
空间复杂度:O(N)。
代码用golang编写。代码如下:
package main
import (
"fmt"
"math"
)
func main() {
if true {
arr := []int{3, 2, 1, 2, 4, 4}
ret := minCost1(arr)
fmt.Println(ret)
}
if true {
arr := []int{3, 2, 1, 2, 4, 4}
ret := yeah(arr)
fmt.Println(ret)
}
}
const INVALID = math.MaxInt64
// 递归方法,已经把尝试写出
func minCost1(arr []int) int {
if len(arr) < 3 {
return 0
}
min := INVALID
for _, num := range arr {
min = getMin(min, num)
}
for i := 0; i < len(arr); i++ {
arr[i] += len(arr) - min
}
return process1(arr, 1, arr[0], true)
}
// 当前来到index位置,值arr[index]
// pre : 前一个位置的值,可能减掉了一些,所以不能用arr[index-1]
// preOk : 前一个位置的值,是否被它左边的数变有效了
// 返回 : 让arr都变有效,最小代价是什么?
func process1(arr []int, index, pre int, preOk bool) int {
if index == len(arr)-1 { // 已经来到最后一个数了
if preOk || pre < arr[index] {
return 0
} else {
return INVALID
}
//return preOk || pre < arr[index] ? 0 : INVALID;
}
// 当前index,不是最后一个数!
ans := INVALID
if preOk {
for cur := arr[index]; cur >= 0; cur-- {
next := process1(arr, index+1, cur, cur < pre)
if next != INVALID {
ans = getMin(ans, arr[index]-cur+next)
}
}
} else {
for cur := arr[index]; cur > pre; cur-- {
next := process1(arr, index+1, cur, false)
if next != INVALID {
ans = getMin(ans, arr[index]-cur+next)
}
}
}
return ans
}
// 最终的最优解,贪心
// 时间复杂度O(N)
// 请注意,重点看上面的方法
// 这个最优解容易理解,但让你学到的东西不是很多
func yeah(arr []int) int {
if len(arr) < 3 {
return 0
}
n := len(arr)
nums := make([]int, n+2)
nums[0] = math.MaxInt64
nums[n+1] = math.MaxInt64
for i := 0; i < len(arr); i++ {
nums[i+1] = arr[i]
}
leftCost := make([]int, n+2)
pre := nums[0]
change := 0
for i := 1; i <= n; i++ {
change = getMin(pre-1, nums[i])
leftCost[i] = nums[i] - change + leftCost[i-1]
pre = change
}
rightCost := make([]int, n+2)
pre = nums[n+1]
for i := n; i >= 1; i-- {
change = getMin(pre-1, nums[i])
rightCost[i] = nums[i] - change + rightCost[i+1]
pre = change
}
ans := math.MaxInt64
for i := 1; i <= n; i++ {
ans = getMin(ans, leftCost[i]+rightCost[i+1])
}
return ans
}
func getMin(a, b int) int {
if a < b {
return a
} else {
return b
}
}
执行结果如下:

2022-01-12:给定一个正数数组arr,长度为n,下标0~n-1, arr中的0、n-1位置不需要达标,它们分别是最左、最右的位置, 中间位置i需要达标,达标的条件是 : arr[i-1] >的更多相关文章
- LeetCode竞赛题:K 次取反后最大化的数组和(给定一个整数数组 A,我们只能用以下方法修改该数组:我们选择某个个索引 i 并将 A[i] 替换为 -A[i],然后总共重复这个过程 K 次。)
给定一个整数数组 A,我们只能用以下方法修改该数组:我们选择某个个索引 i 并将 A[i] 替换为 -A[i],然后总共重复这个过程 K 次.(我们可以多次选择同一个索引 i.) 以这种方式修改数组后 ...
- (016)给定一个有序数组(递增),敲代码构建一棵具有最小高度的二叉树(keep it up)
给定一个有序数组(递增),敲代码构建一棵具有最小高度的二叉树. 因为数组是递增有序的.每次都在中间创建结点,类似二分查找的方法来间最小树. struct TreeNode { int data; Tr ...
- 作业帮:给定一个整数数组,找出其中两个数相加等于目标值(去重set)
题目描述 给定一个整数数组,找出其中两个数相加等于目标值 输入 [1,3,5,7,9,11] 10 输出 1,9 3,7 代码: import java.util.HashMap; import ja ...
- 刷题之给定一个整数数组 nums 和一个目标值 taget,请你在该数组中找出和为目标值的那 两个 整数
今天下午,看了一会github,想刷个题呢,就翻出来了刷点题提高自己的实际中的解决问题的能力,在面试的过程中,我们发现,其实很多时候,面试官 给我们的题,其实也是有一定的随机性的,所以我们要多刷更多的 ...
- 给定一个整数数组 nums 和一个目标值 target,求nums和为target的两个数的下表
这个是来自力扣上的一道c++算法题目: 给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标. 你可以假设每种输入只会对应一个答案 ...
- 给定一个整数数组nums和一个整数目标值target,请你在该数组中找出和为目标值target的那两个整数,并返回它们的数组下标。
/** * 给定一个整数数组nums和一个整数目标值target,请你在该数组中找出和为目标值target的那两个整数,并返回它们的数组下标. * * 你可以假设每种输入只会对应一个答案.但是,数组中 ...
- 【编程题目】一个整数数组,长度为 n,将其分为 m 份,使各份的和相等,求 m 的最大值★★ (自己没有做出来!!)
45.雅虎(运算.矩阵): 2.一个整数数组,长度为 n,将其分为 m 份,使各份的和相等,求 m 的最大值 比如{3,2,4,3,6} 可以分成 {3,2,4,3,6} m=1; {3,6}{2,4 ...
- 产生一个int数组,长度为100,并向其中随机插入1-100,并且不能重复
产生一个int数组,长度为100,并向其中随机插入1-100,并且不能重复 用一个ArrayList存储1到100然后随机产生0到arraylist.size()之间的数字作为下标然后从arrayli ...
- Java实现产生一个int数组,长度为100,并向其中随机插入1-100,并且不能重复。
public static void main(String[] args){ //创建一个int数组,长度为100, int n = 100; int[] arrayInt = new int[n] ...
- 给定一个无序数组arr,求出需要排序的最短子数组长度。例如: arr = [1,5,3,4,2,6,7] 返回4,因为只有[5,3,4,2]需要排序。
思路 首先从左往右遍历,然后设定一个Max,如果遍历的过程中array[i]大于Max,则置换Max,若小于Max,则指定 k 记录该位置. 然后再从右往左遍历,设定一个Min,在遍历的过程中arra ...
随机推荐
- (转)codeblocks 使用研究
原帖:http://github.tiankonguse.com/blog/2014/10/11/codeblocks-shutcut.html 使用前 使用 codeblocks 前肯定是下载安装 ...
- 【故障公告】cc攻击又来了,雪上加霜的三月
非常非常抱歉!今天 21:20-22:10 左右,肆无忌惮的 cc 攻击又来了,蓄意攻击者很厉害,躲过阿里云云盾的黑洞机制,轻松击垮园子的博客站点,又给大家带来了很大的麻烦,请大家谅解! 今年3月是园 ...
- windows2003 DHCP服务器配置
一.导入光驱 二.安装可选的windows组件 三.双击打开网路服务,安装DHCP/DNS服务器. 注:服务器地址要固定,因此安装时要规划好网络. 四.ip地址范围规划时要预留i出一些p地址.排除ip ...
- 关于报出这样的错误:org.apache.catalina.core.StandardWrapperValve.invoke 在路径为/tt1016_war_exploded的上下文中,Servlet[Servlet.m的解决方法
从23:30开始报错检查,现在才弄好,发出来分享一下 错误界面: 首先,我们需要检查一下我们利用DBUtil.java文件中引用的db文件名称是否正确,(我就是因为没有注意到文件名称是否正确报出500 ...
- 在jsp页面int和String类型的相互转换
浅浅地来做一个对比吧! .java文件 int转成string类型:String s=String.valueOf(int m); String转成int类型:int m=Integer.parseI ...
- 阿里云镜像创建Spring Boot工厂
参考博客:https://blog.csdn.net/qq_40052237/article/details/115794368 http://start.aliyun.com
- day07-SpringBoot接收参数相关注解
SpringBoot接收参数相关注解 1.基本介绍 SpringBoot接收客户端提交数据/参数会使用到相关注解 详解@PathVariable.@RequestHeader.@ModelAttrib ...
- 从零开始学Java系列之Java是什么?它到底是个啥?
全文大约[5000]字,不说废话,只讲可以让你学到技术.明白原理的纯干货!文章带有丰富案例及配图,只为让你更好的理解和运用文中的技术概念,给你带来具有足够的思想启迪...... ----------- ...
- DOM选择器之元素其他节点选择器
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- react中类组件、函数组件、state、单层遍历、多层遍历、先遍历后渲染、if-else、三目运算符
1.回顾 module.exports = { entry: {}, output: {}, plugins: [], module: {}, resolve: {}, devServe: {} } ...