日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

最少交换次数python_leetcode第200周赛第三题leetcode1536. 排布二进制网格的最少交换次数...

發布時間:2024/7/23 python 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 最少交换次数python_leetcode第200周赛第三题leetcode1536. 排布二进制网格的最少交换次数... 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

leetcode1536. 排布二進制網格的最少交換次數

給你一個 n x n 的二進制網格 grid,每一次操作中,你可以選擇網格的 相鄰兩行 進行交換。

一個符合要求的網格需要滿足主對角線以上的格子全部都是 0 。

請你返回使網格滿足要求的最少操作次數,如果無法使網格符合要求,請你返回 -1 。

主對角線指的是從 (1, 1) 到 (n, n) 的這些格子。

示例 1:

輸入:grid = [[0,0,1],[1,1,0],[1,0,0]]

輸出:3

示例 2:

輸入:grid = [[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0]]

輸出:-1

解釋:所有行都是一樣的,交換相鄰行無法使網格符合要求。

示例 3:

輸入:grid = [[1,0,0],[1,1,0],[1,1,1]]

輸出:0

提示:n == grid.length

n == grid[i].length

1 <= n <= 200

grid[i][j] 要么是 0 要么是 1 。

方法:貪心+后綴0

思路:

首先我們考慮題意,成功變換之后,對于i行,這一行需要有n-i-1個后綴0,grid[i][i+1]......grid[i][-1]都為0。對于最后一行,不需要有后綴0。

由于我們只能變換相鄰的兩行,對于列是改變不了的。那么現存的每一行的后綴0的數量是不會改變的,因此,我們使用一個數組row_zeros,來保存每一行的后綴0數量,當需要交換的時候,只需要交換這個數組中的對應兩行的值,而不需要交換grid,大大減少了時間復雜度。也就是說,在遍歷完grid,計算出row_zeros之后,我們就不需要grid了。

下面我們考慮如何計算。因為越上面的行,對后綴0的要求越高,所以我們從i=0行開始往下遍歷,直到倒數第二行(因為最后一行不需要)。遍歷的過程中,可能出現幾種情況:row_zeros[i] >= n-i-1;說明該行已經滿足條件了,那么我們這一行就不需要替換了。(不用擔心這一行搶了后面需要的行,因為后面的行要求肯定比這一行低。也不用擔心這一行沒有用更好的行,比如這一行后綴和要求5,這一行是5,后面還有一行后綴和是6,因為5已經滿足了條件,后面的6一定可以滿足它所對應的那一行的條件,不會造成影響,盡可能的少的進行行的變換。)

如果小于,那么這行需要互換,我們從這一行下面的i+1開始往后遍歷,找到第一個滿足條件的行(貪心,第一個找到的需要變換的次數最小)。然后將這一行往上一行一行交換到i行,交換的時候只需要互換row_zeros,交換使用res計數。

如果遍歷到了末尾行還沒找到滿足要求的,那么說明答案不存在,直接返回-1。

遍歷完所有行,返回計數的res。

代碼:

Python3:

class Solution:

def minSwaps(self, grid: List[List[int]]) -> int:

res = 0

n = len(grid)

# row_zeros[i]表示i行的后綴0個數

row_zeros = [0] * n

# 遍歷,填寫row_zeros

for i in range(n):

for j in range(n-1,-1,-1):

if grid[i][j] == 0:

row_zeros[i] += 1

else:

break

# 從第一行開始遍歷,到倒數第二行

for i in range(n-1):

# 如果該行的后綴0滿足要求,pass

if row_zeros[i] >= n-i-1:

pass

# 不符合要求,從下一行開始,找到第一個滿足條件的

else:

for j in range(i+1,n):

if row_zeros[j] >= n-i-1:

break

# 找到這一行,將符合條件這個一次一次往上面互換,換到i行

# 互換的時候,只需要互換row_zeros對應的值即可,不需要互換grid

if row_zeros[j] >= n-i-1:

for k in range(j,i,-1):

row_zeros[k],row_zeros[k-1] = row_zeros[k-1],row_zeros[k]

res += 1

# 如果沒找到,說明不存在符合的i行的行,返回-1

else:

return -1

# 最后返回res

return res

cpp:

class Solution {

public:

int minSwaps(vector>& grid) {

int res = 0;

int n = grid.size();

// row_zeros[i]表示i行的后綴0個數 vector row_zeros(n,0);

// 遍歷,填寫row_zeros for (int i = 0; i < n; ++i)

for (int j = n-1;j > -1;--j){

if (grid[i][j] == 0)

row_zeros[i] += 1;

else break;

}

// 從第一行開始遍歷,到倒數第二行 for (int i = 0; i < n-1; ++i){

// 如果該行的后綴0滿足要求,pass if (row_zeros[i] >= n-i-1) continue;

// 不符合要求,從下一行開始,找到第一個滿足條件的 else{

int j = i+1;

for (;j < n-1; ++j){

if (row_zeros[j] >= n-i-1){

break;

}

}

// 找到這一行,將符合條件這個一次一次往上面互換,換到i行 // 互換的時候,只需要互換row_zeros對應的值即可,不需要互換grid if (row_zeros[j] >= n-i-1){

for (int k = j; k > i; --k){

swap(row_zeros[k],row_zeros[k-1]);

res ++;

}

}

// 如果沒找到,說明不存在符合的i行的行,返回-1 else return -1;

}

}

// 最后返回res return res;

}

};

結果:

總結

以上是生活随笔為你收集整理的最少交换次数python_leetcode第200周赛第三题leetcode1536. 排布二进制网格的最少交换次数...的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。