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 ...
随机推荐
- jar包与war包的部署
前言 Spring Boot支持传统部署和更现代的部署形式.jar跟war都支持,这里参考springboot参考手册学习记录 传统部署:https://docs.spring.io/spring-b ...
- JsonResult向前端返回值,报错500
1,问题原因 因为返回信息为json对象,我在controller方法所在的入口类上,添加的注解是:@Controller 而@Controller是不适合返回json内容的 2,解决方法 方法一:不 ...
- Hadoop-HA节点介绍
设计思想 hadoop2.x启用了主备节点切换模式(1主1备) 当主节点出现异常的时候,集群直接将备用节点切换成主节点 要求备用节点马上就要工作 主备节点内存几乎同步 有独立的线程对主备节点进行监控健 ...
- 保姆级本地maven安装配置步骤【Windows】
一.前期准备 1.首先需要安装并配置好本地JDK(WIN+R输入cmd,输入java -version如下图) 2.下载maven到本地(链接Maven – Download Apache Maven ...
- 前后端分离项目,配置问题导致后端session丢失问题
今天遇到一个巨坑,后端写了获取验证码接口,以及验证验证码接口 获取验证码接口: /// <summary> /// 获取验证码 /// </summary> /// <r ...
- 股票数据定向爬虫.py(亲测有效)
import requests from bs4 import BeautifulSoup import traceback import re def getHTMLText(url,code='u ...
- Rancher系列文章-Rancher v2.6使用脚本实现导入集群
概述 最近在玩 Rancher, 先从最基本的功能玩起, 目前有几个已经搭建好的 K8S 集群, 需要批量导入, 发现官网已经有批量导入的文档了. 根据 Rancher v2.6 进行验证微调后总结经 ...
- webrtc QOS笔记三 Nack机制浅析
nack源码浅析 nack源码浅析 Video Nack nack模块 nack list keyFrame list & recovered list nack 发送的策略 nack 模块的 ...
- 数据泵:oracle数据泵导入导出部分用户
问题描述:需要将140服务器中的tbomnew实例下的部分用户导入到118服务器下的tbompx实例中,本次导入导出的两个数据库均为19C 部分用户名:CORE,MSTDATA,BOMMGMT,CFG ...
- Survivor
Survivor (https://codeforces.com/group/L9GOcnr1dm/contest/422378/problem/F) 血的教训 比较有意思的一个贪心题 简单翻译一下题 ...