题目重现:
思路解析:
这个题乍一看会感觉题意很清晰,但是解题思路很迷茫,这个时候就需要我们结合(面向)样例进行编程,具体的来看到底是怎么得到这个输出的.通过"观察法",我们发现每一个输出中都有很多的0,而且根据简单的代数知识我们知道,这个答案里面有m*n个未知数,而只有m+n-1个方程(m,n表示rowSum.size(),colSum.size()...而减一是因为,sum(rowSum)==sum(colSum)).也就是说很显然解不唯一,我们只有尽可能的找一个最可能满足条件的方法.样例中的许多0其实正表明了一种思路,即->使用min(rowSum[i],colSum[j])作为matrix[i][j].
到这里我们其实已经有了整体的思路,matrix[i][j]=min(rowSum[i],colSum[j]). 同时rowSum[i]-=min(...)而colSum[i]-=min(...)(精髓所在,通过减法把不容易让计算机明白的循环变量触发改变条件更加直观化,即==0,也更加有利于从理论上证明此法的正确性,详见官方题解,这里只简单说明一下)其实这样操作会发现很容易就rowSum[i]为0或者colSum[i]为0,而一旦为0,那么此行或者此列的剩下的就应该全为0
思路正确性简述:假设我们按照行优先的顺序进行matrix的赋值,比较显然的是我们走完一行时,该行的rowSum[i]==0,(每进行一次matrix[i][k]的赋值,k从0...n-1,rowSum[i]与colSum[k]都要有一个为0,显然不可能到了最后(也就是k==n-1),rowSum[i]还非0,这与rowSum[i]<= sum(colSum)矛盾),这样每一行走下去,每一行都为0,而列也是对称的含义.
代码如下:
vector<vector<int>> restoreMatrix(vector<int>& rowSum, vector<int>& colSum) {
int rowCnt=rowSum.size(),colCnt=colSum.size();
vector<vector<int>> arr(rowCnt,vector<int> (colCnt,0));
for(int i=0;i<rowCnt;i++)
for(int j=0;j<colCnt;j++){ //题解上是用while(i<rowCnt&&j<colCnt)代码逻辑更清晰
//我是严格按照i行j列,更易于和题意结合
if(colSum[j]==0) continue;
int minValue=rowSum[i]>colSum[j]?colSum[j]:rowSum[i];
arr[i][j]=minValue;
rowSum[i]-=minValue;
colSum[j]-=minValue;
if(rowSum[i]==0) break;
}
return arr;
}
感觉写题解,尝试着记录自己的解题思路,尝试讲解题目思路,帮助我发现了之前可能根本没有注意到的问题,并且尝试解决他们,通过更深入的思考,加深了记忆,也更能定位自己的薄弱之处,是code时bug太多,还是看不透题意(定位不到算法,以及数据结构),或者涉及到根本不了解的知识点.
希望看到这里的读者尝试去写写博客,作为学习笔记就好