【LeetCode周赛】第 288 场周赛(Go语言实现版)

原创不易,未经允许,请勿转载。

代码收录在 https://github.com/jiang4869/go-algorithm 欢迎给个star

6037. 按奇偶性交换后的最大数字

按奇偶性交换后的最大数字

题意

给定一个数字num,可以把num中奇偶性相同的任意两位数字(即,都是奇数或者偶数)。改操作可以进行任意次数。

思路

因为go语言里面string是不可以修改的,所以只能先把数字转成int数组。
使用类似冒泡排序的思想,通过两个数的奇偶性和大小关系判断是否需要交换。具体看下方代码实现

代码实现

func largestInteger(num int) int {
	arr := make([]int, 0) // 注意这里转成数组后,数字是倒叙的
	for true {
		arr = append(arr, num%10)
		num /= 10
		if num == 0 {
			break
		}
	}
	for i := 0; i < len(arr); i++ {
		for j := i + 1; j < len(arr); j++ {
			if arr[i]%2 == arr[j]%2 && arr[i] > arr[j] {  // 奇偶性相同并且前面的数比后面的数大的话,就交换
				arr[i], arr[j] = arr[j], arr[i]
			}
		}
	}
	num = 0 // 最后把数组转成最后的数字
	for i := len(arr) - 1; i >= 0; i-- {
		num = num*10 + arr[i]
	}

	return num
}

6038. 向表达式添加括号后的最小结果

向表达式添加括号后的最小结

题意

给一个加法表达式,仅有两个数字和一个加号组成。需要向表达式中添加一个括号,使得最后的计算结果最小。
例如247+38,添加括号后2(47+38),结果为2*(47+38) = 2*85 = 170
左括号一定要在+号左侧,右括号一定要在+号右侧。并且添加后还要是一个合法的数学表达式。

思路

可以枚举括号添加的位置。例如对247+38这个表达式添加括号的话,左括号可能添加的情况有(2472(4724(7这三种。相当于是把一个数分割成了两个数(当括号在最左端时例外)

代码实现

func minimizeResult(expression string) string {
	splits := strings.Split(expression, "+")
	var minNum int32
	minNum = math.MaxInt32
	res := ""
	for i := 0; i <= len(splits[0]); i++ {
		for j := 0; j <= len(splits[1]); j++ {
			num1 := splits[0][0:i]
			num2 := splits[0][i:]
			num3 := splits[1][0:j]
			num4 := splits[1][j:]
            if len(num3) == 0 {  // 右括号不能再第二个数的最左右边,例如)24  这种情况是不合法的
				continue
			}
			if len(num2) == 0 { // 左括号不能再第一个数的最右边,例如247(  这种情况是不合法的
				continue
			}
			var tmp int32
			tmp = 1
			if len(num1) > 0 {
				tmp *= toNum(num1)
			}
			if len(num4) > 0 {
				tmp *= toNum(num4)
			}
			n2 := toNum(num2)
			n3 := toNum(num3)
			tmp *= n2 + n3
			if tmp < minNum {
				minNum = tmp
				res = num1 + "(" + num2 + "+" + num3 + ")" + num4
			}
		}
	}

	return res
}


func toNum(str string) int32 {
	atoi1, _ := strconv.Atoi(str)
	return int32(atoi1)
}

6039. K 次增加后的最大乘积

K 次增加后的最大乘积

题意

给定一个数组nums和一个整数k。可以选择数组中的任意一个元素增加1。问操作k次后,nums数组最大的乘积是多少。

思路

加入我们选择数组中的一个元素a进行加1。其他元素的乘积为num。原数组最后乘积为a*num,当a加一后,最后乘积增加了num。根据贪心的思想,要使得最后的乘积最大,那么每次选择一个元素a后,剩余元素的乘积num越大,则最后的乘积也就越大。所以选择的元素a要最小。

代码实现

使用container中的heap来实现最小堆。每次取出堆顶的元素进行+1操作


type IntHeap struct {
	sort.IntSlice
}

func (h IntHeap) Push(x interface{}) {

}
func (h IntHeap) Pop() interface{} {
	return nil
}

const mod = int(1e9 + 7)

func maximumProduct(nums []int, k int) int {
	que := IntHeap{nums}
	heap.Init(&que)
	for k > 0 {
		que.IntSlice[0]++
		heap.Fix(&que, 0)
		k--
	}
	res := 1
	for _, val := range que.IntSlice {
		res = res * val % mod
	}
	return res
}

6040. 花园的最大总美丽值

花园的最大总美丽值

题意

n个花园,每个花园有flowers[i]朵花,给你一个newFlowers,表示还可以额外中的花的最大数目(不一定要种到这么多),同时给你的还有整数targetfullpartial
如果一个花园有 至少 target 朵花,那么这个花园称为 完善的 ,花园的 总美丽值 为以下分数之 和 :

  • 完善 花园数目乘以 full.
  • 剩余 不完善 花园里,花的 最少数目 乘以 partial 。如果没有不完善花园,那么这一部分的值为 0 。

问种最多 newFlowers 朵花以后,能得到的 最大 总美丽值。

思路

复制一个flowers数组nums,然后对flowers进行从大到小排序,对nums进行从小到大排序。
记录nums数组的前缀和。
枚举完善的花园数目,对于剩余不完善的部分,通过二分判断最少的花的数量是多少。
二分判断中的judge函数为func(nf int64, mid int, pos int)。nf为还可以种的花的数量,mid最少的花的数量。pos表示查找的区间nums[0:pos)。

代码实现

刚开始写的时候不知道go里面有现成的二分查找,所以手写了一个lower_bound。
lower_bound函数类似于c++中的lower_bound,找到第一个大于等于key的元素的位置。

func maximumBeauty(flowers []int, newFlowers int64, target, full, partial int) int64 {
	var res int64
	nums := make([]int, len(flowers))
	copy(nums, flowers)
	sort.Slice(flowers, func(i, j int) bool {
		return flowers[i] > flowers[j]
	})
	pre := make([]int64, len(flowers)+10)
	size := len(flowers)
	if flowers[size-1] >= target {
		res = int64(size) * int64(full)
		return res
	}

	sort.Ints(nums)
	for idx := range nums {
		pre[idx+1] = int64(nums[idx]) + pre[idx]
	}

	judge := func(nf int64, mid int, pos int) bool {
		p := lowerBound(nums, 0, pos, mid)
		var tmp int64
		tmp = int64(p)*int64(mid) - pre[p]
		return tmp <= nf
	}

	for idx, val := range flowers {
		if val >= target {
			continue
		}
		l, r := flowers[size-1], target-1
		tmp := 0
		for l <= r {
			mid := l + (r-l)/2
			if judge(newFlowers, mid, size-idx) {
				tmp = int(max(int64(mid), int64(tmp)))
				l = mid + 1
			} else {
				r = mid - 1
			}
		}
		res = max(res, int64(full)*int64(idx)+int64(partial)*int64(tmp))
		newFlowers -= int64(target - val)
		if newFlowers <= 0 {
			return res
		}
	}

	if newFlowers >= 0 {
		res = max(res, int64(full)*int64(size))
	}

	return res
}

func max(a, b int64) int64 {
	if a > b {
		return a
	} else {
		return b
	}
}

func lowerBound(nums []int, begin, end int, key int) int {
	l, r := begin, end
	for l < r {
		mid := l + (r-l)/2
		if nums[mid] >= key {
			r = mid
		} else {
			l = mid + 1
		}
	}
	return l
}

如果这篇文章对您有所帮助,麻烦点个一键三连。

原创不易,未经允许,请勿转载。

博客主页:https://xiaojujiang.blog.csdn.net/

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

jiangxiaoju

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值