【算法】2037. 使每位学生都有座位的最少移动次数(多语言实现)

简介: 一个房间里有 n 个座位和 n 名学生,房间用一个数轴表示。给你一个长度为 n 的数组 seats ,其中 seats[i] 是第 i 个座位的位置。同时给你一个长度为 n 的数组 students ,其中 students[j] 是第 j 位学生的位置。你可以执行以下操作任意次: 增加或者减少第 i 位学生的位置,每次变化量为 1 (也就是将第 i 位学生从位置 x 移动到 x + 1 或者 x - 1)请你返回使所有学生都有座位坐的 最少移动次数 ,并确保没有两位学生的座位相同。请注意,初始时有可能有多个座位或者多位学生在 同一 位置。

2037. 使每位学生都有座位的最少移动次数:

一个房间里有 n 个座位和 n 名学生,房间用一个数轴表示。给你一个长度为 n 的数组 seats ,其中 seats[i] 是第 i 个座位的位置。同时给你一个长度为 n 的数组 students ,其中 students[j] 是第 j 位学生的位置。

你可以执行以下操作任意次:

  • 增加或者减少第 i 位学生的位置,每次变化量为 1 (也就是将第 i 位学生从位置 x 移动到 x + 1 或者 x - 1

请你返回使所有学生都有座位坐的 最少移动次数 ,并确保没有两位学生的座位相同。

请注意,初始时有可能有多个座位或者多位学生在 同一 位置。

样例 1:

输入:
    seats = [3,1,5], students = [2,7,4]
    
输出:
    4
    
解释:
    学生移动方式如下:
    - 第一位学生从位置 2 移动到位置 1 ,移动 1 次。
    - 第二位学生从位置 7 移动到位置 5 ,移动 2 次。
    - 第三位学生从位置 4 移动到位置 3 ,移动 1 次。
    总共 1 + 2 + 1 = 4 次移动。

样例 2:

输入:
    seats = [4,1,5,9], students = [1,3,2,6]
    
输出:
    7
    
解释:
    学生移动方式如下:
    - 第一位学生不移动。
    - 第二位学生从位置 3 移动到位置 4 ,移动 1 次。
    - 第三位学生从位置 2 移动到位置 5 ,移动 3 次。
    - 第四位学生从位置 6 移动到位置 9 ,移动 3 次。
    总共 0 + 1 + 3 + 3 = 7 次移动。

样例 3:

输入:
    seats = [2,2,6,6], students = [1,3,2,6]
    
输出:
    4
    
解释:
    学生移动方式如下:
    - 第一位学生从位置 1 移动到位置 2 ,移动 1 次。
    - 第二位学生从位置 3 移动到位置 6 ,移动 3 次。
    - 第三位学生不移动。
    - 第四位学生不移动。
    总共 1 + 3 + 0 + 0 = 4 次移动。

提示:

  • n == seats.length == students.length
  • 1 <= n <= 100
  • 1 <= seats[i], students[j] <= 100

分析

  • 面对这道算法题目,我陷入了沉思。
  • 如果所有学生,都在座位的左边,或者都在座位的右边,一下子就能想明白。
  • 交叉的情况下呢?

学生1-座位1-学生2-座位2

  • 这时候学生2可能到座位1比到座位2近。
  • 但是别忘了,座位2一定要有人坐,所以学生2到座位2间的距离是必然不能省略的,不管是学生1去坐还是学生2去坐,那段路总是有人要走。
  • 学生1一定要坐一个座位,不管是去坐座位1还是座位2,学生1到座位1之间的距离也是不能省略的。
  • 只有座位1和学生2之间的距离可以省略。
  • 这样思考具有片面性,但是事实证明,这样考虑是对的,贪心算法,局部最优解。
  • 所以学生和座位排好顺序,按顺序坐吧。

题解

java

class Solution {
    public int minMovesToSeat(int[] seats, int[] students) {
        Arrays.sort(seats);
        Arrays.sort(students);

        int ans = 0;
        int n = seats.length;
        for (int i = 0; i < n; ++i) {
            ans += Math.abs(seats[i] - students[i]);
        }
        return ans;
    }
}

c

int cmp(const void *a, const void *b) {
    return (*(int *) a - *(int *) b);
}

int minMovesToSeat(int* seats, int seatsSize, int* students, int studentsSize){
    qsort(seats, seatsSize, sizeof(int), cmp);
    qsort(students, studentsSize, sizeof(int), cmp);

    int ans = 0;
    for (int i = 0; i < seatsSize; ++i) {
        ans += abs(seats[i] - students[i]);
    }
    return ans;
}

c++

class Solution {
public:
    int minMovesToSeat(vector<int>& seats, vector<int>& students) {
        sort(seats.begin(), seats.end());
        sort(students.begin(), students.end());

        int ans = 0;
        int n = seats.size();
        for (int i = 0; i < n; ++i) {
            ans += abs(seats[i] - students[i]);
        }
        return ans;
    }
};

python

class Solution:
    def minMovesToSeat(self, seats: List[int], students: List[int]) -> int:
        seats.sort()
        students.sort()

        ans = 0
        for i in range(len(seats)):
            ans += abs(seats[i] - students[i])
        return ans
        

go

func minMovesToSeat(seats []int, students []int) int {
    sort.Ints(seats)
    sort.Ints(students)
    
    ans := 0
    n := len(seats)
    for i := 0; i < n; i++ {
        if seats[i] > students[i] {
            ans += seats[i] - students[i]
        } else {
            ans += students[i] - seats[i]
        }
    }
    return ans
}

rust

impl Solution {
    pub fn min_moves_to_seat(mut seats: Vec<i32>, mut students: Vec<i32>) -> i32 {
        seats.sort();
        students.sort();

        let mut ans = 0;
        let length = seats.len();
        (0..length).for_each(|i| {
            ans += (seats[i] - students[i]).abs();
        });
        ans
    }
}

在这里插入图片描述


原题传送门:https://leetcode-cn.com/problems/minimum-number-of-moves-to-seat-everyone/


非常感谢你阅读本文~
放弃不难,但坚持一定很酷~
希望我们大家都能每天进步一点点~
本文由 二当家的白帽子:https://developer.aliyun.com/profile/sqd6avc7qgj7y 博客原创~

相关文章
|
3月前
|
自然语言处理 Rust 算法
【算法】13. 罗马数字转整数(多语言实现)
罗马数字包含以下七种字符: I, V, X, L,C,D 和 M。 | 字符 | 数值 | |--|--| | I | 1 | | V | 5 | | X | 10 | | L | 50 | | C | 100 | | D | 500 | | M | 1000 | 例如, 罗马数字 2 写做 II ,即为两个并列的 1。12 写做 XII ,即为 X + II 。 27 写做 XXVII, 即为 XX + V + II 。 通常情况下,罗马数字中小的数字在大的数字的右边。但也存在特例,例如 4 不写做 IIII,而是 IV。数字 1 在数字 5 的左边,所表示的数等于大数 5 减小数 1
【算法】13. 罗马数字转整数(多语言实现)
|
7月前
|
自然语言处理 Rust 算法
【算法】9. 回文数(多语言实现)
给你一个整数 x ,如果 x 是一个回文整数,返回 true ;否则,返回 false 。 回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。例如,121 是回文,而 123 不是。
|
7天前
|
自然语言处理 Rust 算法
【算法】15. 三数之和(多语言实现)
给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i != j、i != k 且 j != k ,同时还满足 nums[i] + nums[j] + nums[k] == 0 。请 你返回所有和为 0 且不重复的三元组。 注意:答案中不可以包含重复的三元组。
|
4月前
|
自然语言处理 Rust 算法
【算法】12. 整数转罗马数字(多语言实现)
罗马数字包含以下七种字符: I, V, X, L,C,D 和 M。 字符 数值 I 1 V 5 X 10 L 50 C 100 D 500 M 1000 例如, 罗马数字 2 写做 II ,即为两个并列的 1。12 写做 XII ,即为 X + II 。 27 写做 XXVII, 即为 XX + V + II 。 通常情况下,罗马数字中小的数字在大的数字的右边。但也存在特例,例如 4 不写做 IIII,而
|
5月前
|
自然语言处理 Rust 算法
【算法】11. 盛最多水的容器(多语言实现)
给定一个长度为 n 的整数数组 height 。有 n 条垂线,第 i 条线的两个端点是 (i, 0) 和 (i, height[i]) 。 找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。 返回容器可以储存的最大水量。 说明: 你不能倾斜容器。
【算法】11. 盛最多水的容器(多语言实现)
|
6月前
|
自然语言处理 Rust 算法
【算法】10. 正则表达式匹配(多语言实现)
给你一个字符串 s 和一个字符规律 p,请你来实现一个支持 . 和 * 的正则表达式匹配。 . 匹配任意单个字符 * 匹配零个或多个前面的那一个元素 所谓匹配,是要涵盖 整个 字符串 s的,而不是部分字符串。
|
8月前
|
自然语言处理 Rust 算法
【算法】8. 字符串转换整数 (atoi)(多语言实现)
请你来实现一个 myAtoi(string s) 函数,使其能将字符串转换成一个 32 位有符号整数(类似 C/C++ 中的 atoi 函数)。 函数 myAtoi(string s) 的算法如下: 读入字符串并丢弃无用的前导空格 检查下一个字符(假设还未到字符末尾)为正还是负号,读取该字符(如果有)。 确定最终结果是负数还是正数。 如果两者都不存在,则假定结果为正。 读入下一个字符,直到到达下一个非数字字符或到达输入的结尾。字符串的其余部分将被忽略。 将前面步骤读入的这些数字转换为整数(即,"123" -> 123, "0032" -> 32)。如果没有读
|
10月前
|
存储 Rust 自然语言处理
【算法】7. 整数反转(多语言实现)
给你一个 32 位的有符号整数 x ,返回将 x 中的数字部分反转后的结果。 如果反转后整数超过 32 位的有符号整数的范围 [−231, 231 − 1] ,就返回 0。 假设环境不允许存储 64 位整数(有符号或无符号)。
|
12月前
|
Rust 自然语言处理 搜索推荐
七大排序算法的多语言代码实现
七大排序算法的多语言代码实现
39 0
|
12月前
|
Rust 自然语言处理 算法
【算法】6. Z 字形变换(多语言实现)
将一个给定字符串 s 根据给定的行数 numRows ,以从上往下、从左到右进行 Z 字形排列。