【刷题打卡】1040. 移动石子直到连续 II

204 阅读2分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

一、题目描述:

1040. 移动石子直到连续 II - 力扣(LeetCode) (leetcode-cn.com)

在一个长度 无限 的数轴上,第 i 颗石子的位置为 stones[i]。如果一颗石子的位置最小/最大,那么该石子被称作 端点石子

每个回合,你可以将一颗端点石子拿起并移动到一个未占用的位置,使得该石子不再是一颗端点石子。

值得注意的是,如果石子像 stones = [1,2,5] 这样,你将 无法 移动位于位置 5 的端点石子,因为无论将它移动到任何位置(例如 0 或 3),该石子都仍然会是端点石子。

当你无法进行任何移动时,即,这些石子的位置连续时,游戏结束。

要使游戏结束,你可以执行的最小和最大移动次数分别是多少? 以长度为 2 的数组形式返回答案:answer = [minimum_moves, maximum_moves]

 

示例 1:

输入:[7,4,9]
输出:[1,2]
解释:
我们可以移动一次,4 -> 8,游戏结束。
或者,我们可以移动两次 9 -> 54 -> 6,游戏结束。

示例 2:

输入:[6,5,4,3,10]
输出:[2,3]
解释:
我们可以移动 3 -> 8,接着是 10 -> 7,游戏结束。
或者,我们可以移动 3 -> 7, 4 -> 8, 5 -> 9,游戏结束。
注意,我们无法进行 10 -> 2 这样的移动来结束游戏,因为这是不合要求的移动。

示例 3:

输入:[100,101,104,102,103]
输出:[0,0]

 

提示:

  • 3 <= stones.length <= 10^4
  • 1 <= stones[i] <= 10^9
  • stones[i] 的值各不相同。

二、思路分析:

首先排序

最大值,计算中间相邻的数的差 + 两边相邻数的差的较大者 最小值

  • 遍历数组,找到最小的 j, 使得 stones[j] - stones[i] + 1 >= len(stones), 说明所有数字可以放在者两个数中间,计算其中的空位,和 min 比较。
  • 如果 stones[j] - stones[i] + 1 < len(stones), 那么就需要移动 len(stones) - (j - i + 1) 次
  • 特别的,[3,4,5, 10], 这种无法移动其中一个端点,需要特殊处理

三、AC 代码:

func numMovesStonesII(stones []int) []int {
	sort.Ints(stones)
	max := 0
	min := 2 << 31
	for i := 1; i < len(stones); i++ {
		max += (stones[i] - stones[i-1] - 1)
	}
	if max == 0 {
		return []int{0, 0}
	}
	if max - (stones[1] - stones[0] - 1) == 0 || max - (stones[len(stones)-1] - stones[len(stones)-2] - 1) == 0 {
		if max - (stones[1] - stones[0] - 1) == 0 {
			min = Min(2, stones[1] - stones[0] - 1)
		} else {
			min = Min(2, stones[len(stones)-1] - stones[len(stones)-2] - 1)
		}
		return []int{min, max}
	}
	max -= Min(stones[1] - stones[0] - 1, stones[len(stones)-1] - stones[len(stones)-2] - 1)
	for i := 0; i < len(stones); i++ {
		for j := i + 1; j < len(stones); j++ {
			if stones[j] - stones[i] + 1 >= len(stones) {
				min = Min(min, stones[j] - stones[i] - 1 - (j - i - 1))
				break
			} else {
				min = Min(min, len(stones) - (j - i + 1))
			}
		}
	}
	min = Min(min, len(stones) - 1)
	return []int{min, max}
}

func Min(x, y int) int {
	if x < y {
		return x
	}
	return y
}