首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

2023-12-09:用go语言,给你两个整数数组 arr1 和 arr2, 返回使 arr1 严格递增所需要的最小「操作」数(

2023-12-09:用go语言,给你两个整数数组 arr1 和 arr2,

返回使 arr1 严格递增所需要的最小「操作」数(可能为 0)。

每一步「操作」中,你可以分别从 arr1 和 arr2 中各选出一个索引,

分别为 i 和 j,0

然后进行赋值运算 arr1[i] = arr2[j]。如果无法让 arr1 严格递增,请返回 -1。

输入:arr1 = [1,5,3,6,7], arr2 = [4,3,1]。

输出:2。

答案2023-12-09:

灵捷3.5

大体过程如下:

算法1(makeArrayIncreasing1):

1.对arr2进行排序并去除重复元素,生成新的数组help,并统计cnt为help的长度。

2.通过递归函数process1来计算从arr1的索引i开始到结尾的最小操作数。初始时,i为-1。

3.在process1中,通过二分查找函数find,在arr2中找到第一个大于cur的元素的索引f。

4.使用循环遍历arr1中从i+1到末尾的元素。

• 若当前元素大于cur,则说明可以选择该元素,继续递归调用process1,并将操作数times加1。

• 若f不等于-1且小于arr2的长度,更新cur为arr2[f],同时f加1,times加1。

• 若f等于-1或大于等于arr2的长度,跳出循环。

5.返回递归调用的结果ans,即最小操作数。

算法2(makeArrayIncreasing2):

1.对arr2进行排序并去除重复元素,生成新的数组help,并统计cnt为help的长度。

2.创建dp数组,初始值为-1。

3.通过递归函数process2来计算从arr1的索引i开始到结尾的最小操作数。同时,使用dp数组记录已计算过的结果,以便后续查询。

4.在process2中,若dp[i+1]不等于-1,直接返回dp[i+1]。

5.剩下的过程与makeArrayIncreasing1基本相同,只是将递归调用替换为对dp数组的查询和更新。

6.返回递归调用的结果ans,同时将其保存到dp[i+1]中。

算法3(makeArrayIncreasing3):

1.对arr2进行排序并去除重复元素,生成新的数组arr2,并统计m为arr2的长度。

2.创建dp数组,长度为n+2,并初始化为最大整数。

3.从arr1末尾向前遍历,使用循环计算从索引i开始到结尾的最小操作数。

• 初始化cur为arr1[i],f为在arr2中找到第一个大于cur的元素的索引。

• 初始化dp[i+1]为最大整数,times为0。

• 使用循环遍历arr1中从i+1到末尾的元素,操作步骤与makeArrayIncreasing1和makeArrayIncreasing2相似。

• 若dp[j+1]不等于最大整数,更新dp[i+1]为times+dp[j+1]与dp[i+1]中的较小值。

• 若f不等于-1且小于m,更新cur为arr2[f],同时f加1,times加1。

• 若f等于-1或大于等于m,跳出循环。

4.若dp[0]等于最大整数,返回-1;否则返回dp[0]作为最小操作数。

时间复杂度分析:

• 算法1和算法2的时间复杂度为O(n * m),其中n和m分别为arr1和arr2的长度,因为每个元素都需要遍历一次。

• 算法3的时间复杂度为O(n * m + m * log(m)),其中m为arr2的长度,因为要对arr2进行排序并进行二分查找。

额外空间复杂度分析:

• 算法1和算法2的额外空间复杂度为O(m),用于存储去重后的arr2。

• 算法3的额外空间复杂度为O(m),用于存储去重后的arr2,并且使用了一个大小为n+2的dp数组来记录中间结果。

go完整代码如下:

package main

import (

"fmt"

"math"

"sort"

)

func makeArrayIncreasing1(arr1 []int, arr2 []int) int {

sort.Ints(arr2)

cnt := 1

for i := 1; i 

if arr2[i] != arr2[i-1] {

cnt++

}

}

help := make([]int, cnt)

help[0] = arr2[0]

for i, j := 1, 1; i 

if arr2[i] != arr2[i-1] {

help[j] = arr2[i]

j++

}

}

ans := process1(arr1, help, -1)

if ans == math.MaxInt64 {

return -1

}

return ans

}

func process1(arr1 []int, arr2 []int, i int) int {

if i == len(arr1) {

return 0

} else {

cur := 0

if i == -1 {

cur = math.MinInt64

} else {

cur = arr1[i]

}

f := find(arr2, cur)

ans := math.MaxInt64

times := 0

for j := i + 1; j 

if j == len(arr1) || cur 

next := process1(arr1, arr2, j)

if next != math.MaxInt64 {

ans = min(ans, times+next)

}

}

if f != -1 && f 

cur = arr2[f]

f++

times++

} else {

break

}

}

return ans

}

}

func find(arr2 []int, num int) int {

l := 0

r := len(arr2) - 1

ans := -1

for l 

m := (l + r) / 2

if arr2[m] > num {

ans = m

r = m - 1

} else {

l = m + 1

}

}

return ans

}

func min(a, b int) int {

if a 

return a

}

return b

}

func makeArrayIncreasing2(arr1 []int, arr2 []int) int {

sort.Ints(arr2)

cnt := 1

for i := 1; i 

if arr2[i] != arr2[i-1] {

cnt++

}

}

help := make([]int, cnt)

help[0] = arr2[0]

for i, j := 1, 1; i 

if arr2[i] != arr2[i-1] {

help[j] = arr2[i]

j++

}

}

dp := make([]int, len(arr1)+1)

for i := range dp {

dp[i] = -1

}

ans := process2(arr1, help, -1, dp)

if ans == math.MaxInt64 {

return -1

}

return ans

}

func process2(arr1 []int, arr2 []int, i int, dp []int) int {

if i == len(arr1) {

return 0

} else {

if dp[i+1] != -1 {

return dp[i+1]

}

cur := 0

if i == -1 {

cur = math.MinInt64

} else {

cur = arr1[i]

}

f := find(arr2, cur)

ans := math.MaxInt64

times := 0

for j := i + 1; j 

if j == len(arr1) || cur 

next := process2(arr1, arr2, j, dp)

if next != math.MaxInt64 {

ans = min(ans, times+next)

}

}

if f != -1 && f 

cur = arr2[f]

f++

times++

} else {

break

}

}

dp[i+1] = ans

return ans

}

}

func makeArrayIncreasing3(arr1 []int, arr2 []int) int {

sort.Ints(arr2)

m := 1

for i := 1; i 

if arr2[i] != arr2[m-1] {

arr2[m] = arr2[i]

m++

}

}

n := len(arr1)

dp := make([]int, n+2)

for i := n - 1; i >= -1; i-- {

cur := 0

if i == -1 {

cur = math.MinInt64

} else {

cur = arr1[i]

}

f := find3(arr2, m, cur)

dp[i+1] = math.MaxInt64

times := 0

for j := i + 1; j 

if j == n || cur 

if dp[j+1] != math.MaxInt64 {

dp[i+1] = min(dp[i+1], times+dp[j+1])

}

}

if f != -1 && f 

cur = arr2[f]

f++

times++

} else {

break

}

}

}

if dp[0] == int(^uint(0)>>1) {

return -1

}

return dp[0]

}

func find3(arr2 []int, size int, num int) int {

l := 0

r := size - 1

ans := -1

for l 

m := (l + r) / 2

if arr2[m] > num {

ans = m

r = m - 1

} else {

l = m + 1

}

}

return ans

}

func main() {

if true {

arr1 := []int{1, 5, 3, 6, 7}

arr2 := []int{4, 3, 1}

fmt.Println(makeArrayIncreasing1(arr1, arr2))

}

if true {

arr1 := []int{1, 5, 3, 6, 7}

arr2 := []int{4, 3, 1}

fmt.Println(makeArrayIncreasing2(arr1, arr2))

}

if true {

arr1 := []int{1, 5, 3, 6, 7}

arr2 := []int{4, 3, 1}

fmt.Println(makeArrayIncreasing3(arr1, arr2))

}

}

在这里插入图片描述

  • 发表于:
  • 原文链接https://page.om.qq.com/page/Og5ztNwHE-ZaviH-k3K-74tA0
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

相关快讯

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券