LeetCode 73矩阵置零74搜素二维矩阵75颜色分类
新人公眾號(求支持):bigsai 專注于Java、數據結構與算法,一起進大廠不迷路!
算法文章題解全部收錄在github倉庫bigsai-algorithm,求star!
關注回復進群即可加入力扣打卡群,歡迎劃水。近期打卡:
打卡LeetCode 65有效數字&66加一 &67二進制求和
LeetCode 67二進制求和&68文本左右對齊&69x的平方根
LeetCode 70爬樓梯&71簡化路徑&72編輯距離(dp)
如有幫助,記得對本文一鍵三連!
矩陣置零
題目描述:
給定一個 m x n 的矩陣,如果一個元素為 0,則將其所在行和列的所有元素都設為 0。請使用原地算法。
示例 1:
輸入: [[1,1,1],[1,0,1],[1,1,1] ] 輸出: [[1,0,1],[0,0,0],[1,0,1] ]示例 2:
輸入: [[0,1,2,0],[3,4,5,2],[1,3,1,5] ] 輸出: [[0,0,0,0],[0,4,5,0],[0,3,1,0] ]進階:
一個直接的解決方案是使用 O(mn) 的額外空間,但這并不是一個好的解決方案。
一個簡單的改進方案是使用 O(m + n) 的額外空間,但這仍然不是最好的解決方案。
你能想出一個常數空間的解決方案嗎?
分析:
這道題可謂是一波三折,對于O(m*n)的方法不談了,沒啥好講了。
從O(m+n)的方法說起,一維空間,只要出現0,那么這一行或者這一列就全部變成0,那么就可以用兩個boolean數組解決,一個標記行,一個標記列,遍歷的時候遇到0就把該行和該列標記為true。最終根據兩個boolean數組進行賦值即可。
實現代碼為:
class Solution {public void setZeroes(int[][] matrix) {boolean hang[]=new boolean[matrix.length];boolean lie[]=new boolean[matrix[0].length];for (int i=0;i<matrix.length;i++){for(int j=0;j<matrix[i].length;j++){if(matrix[i][j]==0) {hang[i] = true;lie[j] = true;}}}for(int i=0;i<hang.length;i++){if(hang[i]){for(int j=0;j<lie.length;j++){matrix[i][j]=0;}}}for(int j=0;j<lie.length;j++){if(lie[j]){for(int i=0;i<hang.length;i++){matrix[i][j]=0;}}}} }題目有說到要使用常數級別的額外空間,而這種情況就要考慮空間的復用!這個就想了一下談談我的想法:
這題的核心問題是在根據行或者列遍歷的時候不能第一次遇到就把改行和列置零,說說我的錯誤想法:
- 第一趟按行遍歷,遇到0那么將這一行所有數據特殊的標記起來。 我首先想到的是除0以外標記成負數。
- 第二趟按列遍歷,遇到0直接將該列置為0(行已經遍歷過)。遇到負數的時候置為0.
如果所有數據是正數,那么這是可行的,但是很可疑測試數據有負數,over。。
后來又想逃巧將所有數據換成int的最大值或者最小值,但是不幸的是測試有這兩組數據,把我卡的死死的。
后來只能先用枚舉的方法找到一個數組中不存在的數,因為二維數組是有大小范圍int [m][n]的,所以在[1,m*n+1] 范圍內一定有一個不存在的數可以作為臨時標記。
第二趟按照列遍歷,遇到0直接將該列置為0(行已經遍歷過)。遇到標記的那個數將那個位置數字為0.
實現代碼為:
class Solution {public void setZeroes(int[][] matrix) {boolean jud=false;//int num=1;//找到一個合適的數字用于臨時替換for(int q=1;q<matrix.length*matrix[0].length+2;q++){jud=false;outer:for (int i=0;i<matrix.length;i++){for(int j=0;j<matrix[i].length;j++){if(matrix[i][j]==q) {jud=true;break outer;}}}if(!jud){num=q;break;}}//遍歷行for (int i=0;i<matrix.length;i++){for(int j=0;j<matrix[i].length;j++){if(matrix[i][j]==0){for(int q=0;q<matrix[0].length;q++){if(matrix[i][q]!=0)matrix[i][q]=num;}break;}}}for(int j=0;j<matrix[0].length;j++)//列{for (int i=0;i<matrix.length;i++){if(matrix[i][j]==0){for(int q=0;q<matrix.length;q++){matrix[q][j]=0;}break;}if(matrix[i][j]==num)matrix[i][j]=0;}}} }搜素二維矩陣
編寫一個高效的算法來判斷 m x n 矩陣中,是否存在一個目標值。該矩陣具有如下特性:
每行中的整數從左到右按升序排列。
每行的第一個整數大于前一行的最后一個整數。
示例 1:
示例 2:
示例 3:
輸入:matrix = [], target = 0 輸出:false提示:
m == matrix.length n == matrix[i].length 0 <= m, n <= 100 -104 <= matrix[i][j], target <= 104分析:
這題可以根據數據進行兩次二分,第一次二分對第一列找到對應的行,第二次對對應的行進行二分找到對應的位置。
具體代碼為:
class Solution {public boolean searchMatrix(int[][] matrix, int target) {if(matrix.length==0||matrix[0].length==0)return false;//先對第一行進行二分定位到該列if(matrix[0][0]>target) return false;int l=0,r=matrix.length;while (l<r) {int mid=(l+r)/2;if(matrix[mid][0]==target)return true;if(matrix[mid][0]<target){l=mid+1;}else {r=mid;}}int index=l-1;l=0;r=matrix[0].length;while (l<r) {int mid=(l+r)/2;if(matrix[index][mid]==target)return true;if(matrix[index][mid]<target){l=mid+1;}else {r=mid;}} return false; } }顏色分類
給定一個包含紅色、白色和藍色,一共 n 個元素的數組,原地對它們進行排序,使得相同顏色的元素相鄰,并按照紅色、白色、藍色順序排列。
此題中,我們使用整數 0、 1 和 2 分別表示紅色、白色和藍色。
進階:
你可以不使用代碼庫中的排序函數來解決這道題嗎?
你能想出一個僅使用常數空間的一趟掃描算法嗎?
示例 1:
輸入:nums = [2,0,2,1,1,0] 輸出:[0,0,1,1,2,2]示例 2:
輸入:nums = [2,0,1] 輸出:[0,1,2]示例 3:
輸入:nums = [0] 輸出:[0]示例 4:
輸入:nums = [1] 輸出:[1]提示:
n == nums.length 1 <= n <= 300 nums[i] 為 0、1 或 2分析:
方法比較靈活,可以用雙指針,一個在左,一個在右,遍歷的時候遇到0和2分別分配在左側和右側。
具體實現可用一個left,right標記左右往中間擴散,left左側都是0,right右側都是2,遍歷的時候遇到需要交換的則交換,和快排的思想有些相似。
實現代碼:
class Solution {public void sortColors(int[] nums) {int left=0;int right=nums.length-1;for(int i=0;i<right+1;i++){if(nums[i]==0){int team=nums[left];nums[left++]=0;nums[i]=team;}else if(nums[i]==2){int team=nums[right];nums[right--]=2;nums[i]=team;i--;} }} }結語
原創不易,bigsai請你幫兩件事幫忙一下:
star支持一下, 您的肯定是我在平臺創作的源源動力。
微信搜索「bigsai」,關注我的公眾號,不僅免費送你電子書,我還會第一時間在公眾號分享知識技術。加我還可拉你進力扣打卡群一起打卡LeetCode。
記得關注、咱們下次再見!
總結
以上是生活随笔為你收集整理的LeetCode 73矩阵置零74搜素二维矩阵75颜色分类的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: LeetCode 70爬楼梯71简化路径
- 下一篇: Leetcode 76最小覆盖子串77组