LeetCode.1033-移动石头直到连续(Moving Stones Until Consecutive)

这是小川的第386次更新,第414篇原创

01 看题和准备

今天介绍的是LeetCode算法题中Easy级别的第247题(顺位题号是1033)。在abc位置的数字线上有三块石头。每次,你在一个终点(即最低或最高位置的石头)上拾取一块石头,然后将它移动到这些终点之间的空置位置。

形式上,假设石头当前位于xyz位置,x <y <z。你在x位置或z位置拾取石头,然后将石头移动到整数位置kx <k <zk!= y

当你不能做任何移动时,游戏结束。例如,当石头处于连续的位置时。

当游戏结束时,你可以做出的最小和最大移动次数是多少?将答案作为长度为2的数组返回:answer = [minimum_moves,maximum_moves]

例如:

输入:a = 1,b = 2,c = 5
输出:[1,2]
说明:将石头从5移动到3,或将石头从5移动到4到3。

输入:a = 4,b = 3,c = 2
输出:[0,0]
说明:不能做任何移动。

输入:a = 3,b = 5,c = 1
输出:[1,2]
说明:将石头从1移动到4;或将石头从1移动到2到4。

注意

  • 1 <= a <= 100
  • 1 <= b <= 100
  • 1 <= c <= 100
  • a != b,b != c,c != a

02 解题

先将三个数排序,找出最小值min,中间值mid,最大值max

最小移动步数:既然要移动的步数最少,那就跳着移动,向中间值mid靠拢。

如果三个数都相邻,那么就不需要跳。

如果其中有两个数相邻,即最小值和中间值相邻,或者中间值和最大值相邻,那么就只需要跳一步即可。

如果三个数不相邻,分两种情况:

  • 第一,如果最大值与中间值相差2,那么只需要跳一步,将最小值跳到最大值与中间值之间即可;如果中间值与最小值相差2,那么只需要跳一步,将最大值跳到中间值与最小值之间即可。
  • 第二,任意两数的差值大于2,那就往中间数左右两边相邻的数字上跳,左右两边各跳一次即可。

最多移动步数:既然要移动的步数最多,那就一次只移动一次,向中间值mid靠拢。

最大值max向左移动,移动到mid+1的位置,一共移动了max-mid-1步。

最小值min向右移动,移动到mid-1的位置,一共移动了mid-min-1步。

因此,最多移动步数为(max-mid-1)+(mid-min-1) = max - min - 2

public int[] numMovesStones(int a, int b, int c) {
    int max = Math.max(a, Math.max(b, c));
    int min = Math.min(a, Math.min(b, c));
    int mid = a + b + c - max - min;
    int min_moves = Math.min(1, mid-min-1) +
            Math.min(1, max-mid-1);
    if (mid-min == 2 || max-mid == 2) {
        min_moves = 1;
    }
    int max_moves = max - min - 2;
    return new int[]{min_moves, max_moves};
}

03 小结

算法专题目前已连续日更超过七个月,算法题文章253+篇,公众号对话框回复【数据结构与算法】、【算法】、【数据结构】中的任一关键词,获取系列文章合集。

以上就是全部内容,如果大家有什么好的解法思路、建议或者其他问题,可以下方留言交流,点赞、留言、转发就是对我最大的回报和支持!

原文地址:https://www.cnblogs.com/xiaochuan94/p/11204928.html

时间: 2024-08-29 11:24:30

LeetCode.1033-移动石头直到连续(Moving Stones Until Consecutive)的相关文章

滑动窗口-Moving Stones Until Consecutive II

2020-02-20 16:34:16 问题描述: 问题求解: public int[] numMovesStonesII(int[] stones) { int n = stones.length; Arrays.sort(stones); int min = n; int start = 0; for (int end = 0; end < n; end++) { while (stones[end] - stones[start] + 1 > n) start += 1; int cur

[Swift]LeetCode1033. 边框着色 | Moving Stones Until Consecutive

Given a 2-dimensional grid of integers, each value in the grid represents the color of the grid square at that location. Two squares belong to the same connected component if and only if they have the same color and are next to each other in any of t

leetcode 1040. 移动石子直到连续 II(滑动窗口)

题意: 在一个长度无限的数轴上,第 i 颗石子的位置为 stones[i].如果一颗石子的位置最小/最大,那么该石子被称作端点石子. 每个回合,你可以将一颗端点石子拿起并移动到一个未占用的位置,使得该石子不再是一颗端点石子. 值得注意的是,如果石子像 stones = [1,2,5] 这样,你将无法移动位于位置 5 的端点石子,因为无论将它移动到任何位置(例如 0 或 3),该石子都仍然会是端点石子. 当你无法进行任何移动时,即,这些石子的位置连续时,游戏结束. 要使游戏结束,你可以执行的最小和

LeetCode - 宝石与石头 (No.771)

771 - 宝石与石头 date : Dec.31st, 2019 platform : windows problem description 给定字符串J?代表石头中宝石的类型,和字符串?S代表你拥有的石头.?S?中每个字符代表了一种你拥有的石头的类型,你想知道你拥有的石头中有多少是宝石. J?中的字母不重复,J?和?S中的所有字符都是字母.字母区分大小写,因此"a"和"A"是不同类型的石头. 来源:力扣(LeetCode) 链接:https://leetcod

LeetCode 53. Maximum Subarray 最大连续字段和问题

考察:最大连续字段和问题. 解决问题时间复杂度:O(n) 问题隐含条件:如果给出的数集都是负数,那么最大连续字段和就是,最大的那个负数. eg:{-2,-1}  结果应该输出 -1 而不是 0 int maxSubArray(int* nums, int numsSize) { int maxSum = 0; //维护最大连续字段和 int currentMaxSum = 0;//当前最大和 int nextNum = 0; int singleSum = nums[0]; //存在全是负数,则

LeetCode 128. 最长连续序列(Longest Consecutive Sequence)

题目描述 给定一个未排序的整数数组,找出最长连续序列的长度. 要求算法的时间复杂度为 O(n). 示例: 输入: [100, 4, 200, 1, 3, 2] 输出: 4 解释: 最长连续序列是 [1, 2, 3, 4].它的长度为 4. 解题思路 利用并查集的思想,构造一个map记录数组中以每个数所在的最长连续序列长度.每次遍历到一个数时,首先检查map中是否存在该数,若存在直接跳过,否则作如下更新操作: 找到左右相邻数字是否在map中,若存在则分别记录他们所在的最长连续序列长度,并更新当前的

Leetcode 659.分割数组为连续子序列

分割数组为连续子序列 输入一个按升序排序的整数数组(可能包含重复数字),你需要将它们分割成几个子序列,其中每个子序列至少包含三个连续整数.返回你是否能做出这样的分割? 示例 1: 输入: [1,2,3,3,4,5] 输出: True 解释: 你可以分割出这样两个连续子序列 : 1, 2, 3 3, 4, 5 示例 2: 输入: [1,2,3,3,4,4,5,5] 输出: True 解释: 你可以分割出这样两个连续子序列 : 1, 2, 3, 4, 5 3, 4, 5 示例 3: 输入: [1,2

【LeetCode】128. 最长连续序列

题目 给定一个未排序的整数数组,找出最长连续序列的长度. 要求算法的时间复杂度为O(n). 示例: 输入:[100, 4, 200, 1, 3, 2] 输出:4 解释:最长连续序列是[1, 2, 3, 4].它的长度为4 思路 思路一 先由小到大进行排序 考虑三种情况: 前后相差1,则是连续序列 前后相等,循环continue 最后一个元素,break 代码 def longestConsecutive(nums) -> int: ????if nums: ????????nums.sort()

leetcode宝石与石头

给定字符串J?代表石头中宝石的类型,和字符串?S代表你拥有的石头.?S?中每个字符代表了一种你拥有的石头的类型,你想知道你拥有的石头中有多少是宝石. J?中的字母不重复,J?和?S中的所有字符都是字母.字母区分大小写,因此"a"和"A"是不同类型的石头. 示例 1: 输入: J = "aA", S = "aAAbbbb" 输出: 3 示例 2: 输入: J = "z", S = "ZZ"