病了一场,家庭琐事太多,耽搁了好些日子。看来后面得抓紧时间了!
6. 一幅图像由N X N矩阵的像素点组成,每个像素点4个字节的信息量,将图像顺时针(逆时针)旋转90度。如何做到?
思路:剥洋葱法,由外而内分层进行,以4x4大小的像素点矩阵为例,先从最外圈(黄色)开始调整,然后是内圈(绿色)。
编程实现:
/*
@ clockwise rotate a matrix N x N
*/
void rotateMatrix(int** matrix, int n)
{
if(matrix == NULL || n < 2) return;
//rotate by layer from outer to inner
for(int layer=0; layer<n/2; layer++){
int first = layer;
int last = n - 1 - layer;
for(int i=first; i<last; i++){
int offset = i - first;
int top = matrix[layer][i];
//left -> top
matrix[layer][i] = matrix[last-offset][layer];
//bottom -> left
matrix[last-offset][layer] = matrix[last][last-offset];
//right -> bottom
matrix[last][last-offset] = matrix[i][last];
// top -> right
matrix[i][last] = top;
}
}
}
部分测试代码:
const int N = 10;
int **pMatrix = new int*[N];
for(int i=0; i<N; i++)
pMatrix[i] = new int[N];
cout << "before rotation, matrix is " << endl;
for(int i=0; i<N; i++){
for(int j=0; j<N; j++){
pMatrix[i][j] = i*N + j;
cout << pMatrix[i][j] << " ";
}
cout << endl;
}
rotateMatrix(pMatrix, N);
cout << "after rotation, matrix is " << endl;
for(int i=0; i<N; i++){
for(int j=0; j<N; j++)
cout << pMatrix[i][j] << " ";
cout << endl;
}
delete []pMatrix;
7.M X N大小矩阵中某个元素为0, 则将该元素所在的行和列均置为0
思路:这道题看似简单,其实暗藏机关。如果遍历矩阵,遇到0元素,则将所在行和列均置为0,最后得到0矩阵。为什么呢?不明白的时候可以找个简单的例子推理。一种可行的方法是第一次遍历时候记录下0元素所在的行和列,然后在第二次遍历时将所在行或者列为0的元素置为0即可。
编程实现:
/*
@ if an element in a MxN matrix is 0, its entire row and column is set to 0.
*/
void setZeros(int** matrix, int m, int n)
{
if(matrix==NULL || m<1 || n<1) return;
bool *zerosColumn = new bool[m];
bool *zerosRow = new bool[n];
//initialize zerosColumn and zerosRow
for(int i=0; i<m; i++)
zerosColumn[i] = false;
for(int i=0; i<n; i++)
zerosRow[i] = false;
//count '0' in matrix
for(int i=0; i<m; i++)
for(int j=0; j<n; j++)
if(matrix[i][j] == 0){
zerosColumn[i] = true;
zerosRow[j] = true;
}
for(int i=0; i<m; i++)
for(int j=0; j<n; j++)
{
if(zerosColumn[i]||zerosRow[j])
matrix[i][j] = 0;
}
delete zerosColumn;
delete zerosRow;
}
部分测试代码:
//test setZeros
const int M = 5;const int N = 6;
//int matrix[N][N] = {1,2,3,4};
int **pMatrix = new int*[M];
for(int i=0; i<M; i++)
pMatrix[i] = new int[N];
cout << "before rotation, matrix is " << endl;
for(int i=0; i<M; i++){
for(int j=0; j<N; j++){
pMatrix[i][j] = i*N + j;
if(i==M/2 && j==N/2)
pMatrix[i][j] = 0;
cout << setw(5) << pMatrix[i][j];
}
cout << endl;
}
setZeros(pMatrix,M,N);
cout << "after Zero setting, matrix is " << endl;
for(int i=0; i<M; i++){
for(int j=0; j<N; j++)
cout << setw(5) << pMatrix[i][j];
cout << endl;
}
delete []pMatrix;
8. 假设已有isSubstring方法去判断一个字符串是否为另一个的子字符串;现有S1和S2两个字符串,调用一次isSubstring方法判断两者是否互为旋转式?如“waterbottle”和“bottlewater”互为旋转式。
思路:简单清晰,方法如下:1) 先检查S1和S2的长度是否相等,不等显然不能满足互为旋转式;2)将S1首尾链接组成一个新的字符串S11,然后调用isSubstring判断S2是否为S1的一个字符串。
编程实现:
/*
@ judge s is Substring of t or not.
*/
bool isSubstring(const string& s, const string& t)
{
if(s.length()<1 || t.length()<1)
return false;//NULL is NOT Substring of NULL string.
int n = 0; //index of t
for(int i=0; i<t.length(); i++){
if(t[i] == s[n])
++n;
else if(t[i]==s[0])
n = 1;
else
n=0;
if(n==s.length())
return true;
}
return false;
}
bool isRotateString(const string& str1, const string& str2)
{
if(str1.length() > 0 && str1.length()==str2.length()){
string s1 = string(str1);
s1 += str1;
return isSubstring(str2, s1);
}
return false;
}
部分测试代码如下:
//test isSubstring
string str1 = "world";
string str2 = "Hello wor2ldworworld";
if(isSubstring(str1, str2))
cout << str1 << " is Substring of " << str2 << endl;
else
cout << str1 << " is NOT Substring of " << str2 << endl;
string str3 = "ldwor";
if(isRotateString(str1,str3))
cout << str1 << " is rotated by " << str3 << endl;
else
cout << str1 << " is NOT rotated by " << str3 << endl;