Welcome to Subscribe On Youtube

3189. Minimum Moves to Get a Peaceful Board 🔒

Description

Given a 2D array rooks of length n, where rooks[i] = [xi, yi] indicates the position of a rook on an n x n chess board. Your task is to move the rooks 1 cell at a time vertically or horizontally (to an adjacent cell) such that the board becomes peaceful.

A board is peaceful if there is exactly one rook in each row and each column.

Return the minimum number of moves required to get a peaceful board.

Note that at no point can there be two rooks in the same cell.

 

Example 1:

Input: rooks = [[0,0],[1,0],[1,1]]

Output: 3

Explanation:

Example 2:

Input: rooks = [[0,0],[0,1],[0,2],[0,3]]

Output: 6

Explanation:

 

Constraints:

  • 1 <= n == rooks.length <= 500
  • 0 <= xi, yi <= n - 1
  • The input is generated such that there are no 2 rooks in the same cell.

Solutions

Solution 1: Greedy Algorithm

We can sort all the cars by their x-coordinates, and then allocate the cars to each row in order, calculating the sum of distances from each car to its target position. Then, sort all the cars by their y-coordinates and use the same method to calculate the sum of distances from each car to its target position. Finally, the sum of these two distances is the answer.

The time complexity is $O(n \times \log n)$, and the space complexity is $O(\log n)$. Here, $n$ is the number of cars.

  • class Solution {
        public int minMoves(int[][] rooks) {
            Arrays.sort(rooks, (a, b) -> a[0] - b[0]);
            int ans = 0;
            int n = rooks.length;
            for (int i = 0; i < n; ++i) {
                ans += Math.abs(rooks[i][0] - i);
            }
            Arrays.sort(rooks, (a, b) -> a[1] - b[1]);
            for (int j = 0; j < n; ++j) {
                ans += Math.abs(rooks[j][1] - j);
            }
            return ans;
        }
    }
    
  • class Solution {
    public:
        int minMoves(vector<vector<int>>& rooks) {
            sort(rooks.begin(), rooks.end());
            int ans = 0;
            int n = rooks.size();
            for (int i = 0; i < n; ++i) {
                ans += abs(rooks[i][0] - i);
            }
            sort(rooks.begin(), rooks.end(), [](const vector<int>& a, const vector<int>& b) {
                return a[1] < b[1];
            });
            for (int j = 0; j < n; ++j) {
                ans += abs(rooks[j][1] - j);
            }
            return ans;
        }
    };
    
  • class Solution:
        def minMoves(self, rooks: List[List[int]]) -> int:
            rooks.sort()
            ans = sum(abs(x - i) for i, (x, _) in enumerate(rooks))
            rooks.sort(key=lambda x: x[1])
            ans += sum(abs(y - j) for j, (_, y) in enumerate(rooks))
            return ans
    
    
  • func minMoves(rooks [][]int) (ans int) {
    	sort.Slice(rooks, func(i, j int) bool { return rooks[i][0] < rooks[j][0] })
    	for i, row := range rooks {
    		ans += int(math.Abs(float64(row[0] - i)))
    	}
    	sort.Slice(rooks, func(i, j int) bool { return rooks[i][1] < rooks[j][1] })
    	for j, col := range rooks {
    		ans += int(math.Abs(float64(col[1] - j)))
    	}
    	return
    }
    
  • function minMoves(rooks: number[][]): number {
        rooks.sort((a, b) => a[0] - b[0]);
        let ans = rooks.reduce((sum, rook, i) => sum + Math.abs(rook[0] - i), 0);
        rooks.sort((a, b) => a[1] - b[1]);
        ans += rooks.reduce((sum, rook, j) => sum + Math.abs(rook[1] - j), 0);
        return ans;
    }
    
    

All Problems

All Solutions