• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

2022-01-12把定正数数组arr,长度为n,下标0~n-1, arr的0、n-1位置不需要达标,它们分别是最左、最右的位置, 间位置i需要达标,达标的条件是 : arr[i-1] >

武飞扬头像
福大大架构师每日一题
帮助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
    }
}
学新通

执行结果如下:
学新通


左神java代码

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhhafkga
系列文章
更多 icon
同类精品
更多 icon
继续加载