打印矩阵
题目
转圈打印矩阵(螺旋打印);
旋转矩阵,将矩阵调整成顺时针转动90度之后的形式;
之字形打印矩阵;给定一个矩阵,按照“之”字形的方式打印这个矩阵。
代码
按照书中的方式分别实现了三种打印的方式,书中给出的方法与剑指offer的方法基本一致,稍微仔细看下就可以理解,但是写的话如果大意还是会有问题(对于我来说的)
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
void printEdge(vector<vector<int>> m, int tR, int tC, int dR, int dC)
{
if (tR == dR)
{
for (int i = tC; i <= dC; i++)
cout << m[tR][i] << " ";
}
else if (tC == dC)
{
for (int i = tR; i <= dR; i++)
{
cout << m[i][tC] << " ";
}
}
else
{
int curC = tC;
int curR = tR;
while (curC != dC)
{
cout << m[tR][curC] << " ";
curC++;
}
while (curR != dR)
{
cout << m[curR][dC] << " ";
curR++;
}
while (curC != tC)
{
cout << m[dR][curC] << " ";
curC--;
}
while (curR != tR)
{
cout << m[curR][tC] << " ";
curR--;
}
}
}
void circlePrint1(vector<vector<int>> matrix)
{
int tR = 0;
int tC = 0;
int dR = matrix.size() - 1;
int dC = matrix[0].size() - 1;
while (tR <= dR && tC <= dC)
{
printEdge(matrix, tR, tC, dR, dC);
tR++;
tC++;
dR--;
dC--;
}
cout << endl;
}
/*旋转矩阵*/
void rotateEdge(vector<vector<int>> &m, int tR, int tC, int dR, int dC)
{
int times = dC - tC;
int tmp = 0;
for (int i = 0; i != times; i++)
{
tmp = m[tR][tC + i];
m[tR][tC + i] = m[dR - i][tC];
m[dR - i][tC] = m[dR][dC - i];
m[dR][dC - i] = m[tR + i][dC];
m[tR + i][dC] = tmp;
}
}
void rotate(vector<vector<int>> matrix)
{
int tR = 0;
int tC = 0;
int dR = matrix.size() - 1;
int dC = matrix[0].size() - 1;
while (tR < dR)
{
rotateEdge(matrix, tR, tC, dR, dC);
tR++;
tC++;
dR--;
dC--;
}
for (int i = 0; i <= 3; i++)
{
for (int j = 0; j <= 3; j++)
cout << matrix[i][j] << " ";
cout << endl;
}
cout << endl;
}
//"之"字形打印矩阵
void printLevel(vector<vector<int>> m, int tR, int tC, int dR, int dC, bool f)
{
if (f)
{
while (tR != dR + 1)
cout << m[tR++][tC--] << " ";
}
else
{
while (dR != tR - 1)
cout << m[dR--][dC++] << " ";
}
}
void printMatrixZigZag(vector<vector<int>> matrix)
{
int tR = 0;
int tC = 0;
int dR = 0;
int dC = 0;
int endR = matrix.size() - 1;
int endC = matrix[0].size() - 1;
bool fromUp = false;
while (tR != endR + 1)
{
printLevel(matrix, tR, tC, dR, dC, fromUp);
tR = tC == endC ? tR + 1 : tR;
tC = tC == endC ? tC : tC + 1;
dC = dR == endR ? dC + 1 : dC;
dR = dR == endR ? dR : dR + 1;
fromUp = !fromUp;
}
cout << endl;
}
int main()
{
int len;
cin >> len;
vector<vector<int>> m(len, vector<int>(len, 0));
for (int i = 0; i < len; i++)
{
for (int j = 0; j < len; j++)
cin >> m[i][j];
}
cout << "Circle print of matrix!" << endl;
circlePrint1(m);
cout << "Zigzag print of matrix!" << endl;
printMatrixZigZag(m);
cout << "Rotate of matrix!" << endl;
rotate(m);
getchar();
return 0;
}
找到无序数组中最小的k个数
题目
给定一个无序整型数组arr,找到其中最小的k个数。
要求:排序之后可以得到最小的前k个数,时间复杂度为O(NlogN),要求实现*O(Nlogk)和O(N)*的方法。
代码
按照书中所题,根据最大堆的方式实现了O(Nlogk) 的方法,*O(N)*方法略复杂,未做实现。
#include<iostream>
#include<algorithm>
#define lChild(i) 2 * (i) + 1;
#define rChild(i) 2 * (i) + 2;
using namespace std;
void swap(int* &arr, int a, int b)
{
int tmp = arr[a];
arr[a] = arr[b];
arr[b] = tmp;
}
void heapify(int* in, int len, int i)
{
int left = lChild(i);
int right = rChild(i);
int largest = i;
while (left < len)
{
if (in[left] > in[i])
largest = left;
if (right < len && in[right] > in[largest])
largest = right;
if (largest != i)
swap(in, largest, i);
else
break;
i = largest;
left = lChild(i);
right = rChild(i);
}
}
void heapInsert(int* in, int i, int value)
{
in[i] = value;
while (i != 0)
{
int parent = (i - 1) / 2;
if (in[parent] < in[i])
{
swap(in, parent, i);
i = parent;
}
else
break;
}
}
int* getMinKNum(int* in, int k, int len)
{
if (k < 1 || k > len)
return in;
int* kHeap = new int[k];
for (int i = 0; i < k; i++)
heapInsert(kHeap, i, in[i]);
for (int i = k; i < len; i++)
{
if (in[i] < kHeap[0])
{
kHeap[0] = in[i];
heapify(kHeap, k, 0);
}
}
return kHeap;
}
int main()
{
int len, k;
cin >> len >> k;
int* in = new int[len];
for (int i = 0; i < len; i++)
cin >> in[i];
int* numK = new int[k];
numK = getMinKNum(in, k, len);
for (int i = 0; i < k; i++)
cout << numK[i] << " ";
cout << endl;
getchar();
return 0;
}
需要排序的最短子数组长度
题目
给定一个无序数组arr,求出需要排序的最短子数组长度
例如:arr = [1, 5, 3, 4, 2, 6, 7]返回4,因为只有[5, 4, 3, 2]需要排序。
代码
#include<iostream>
#include<algorithm>
using namespace std;
int getMinLen(int* arr, int len)
{
if (arr == NULL || len < 1)
return 0;
int Min = arr[len - 1];
int noMinIndex = -1;
for (int i = len - 2; i >= 0; i--)
{
if (arr[i] > Min)
noMinIndex = i;
else
Min = min(Min, arr[i]);
}
if (noMinIndex == -1)
return 0;
int Max = arr[0];
int noMaxIndex = -1;
for (int i = 1; i < len; i++)
{
if (arr[i] < Max)
noMaxIndex = i;
else
Max = max(Max, arr[i]);
}
return noMaxIndex - noMinIndex + 1;
}
int main()
{
int len;
cin >> len;
int* in = new int[len];
for (int i = 0; i < len; i++)
cin >> in[i];
int res = getMinLen(in, len);
cout << res << endl;
getchar();
return 0;
}
在数组中找到出现次数大于N/K的数
题目
给定一个整型数组arr,打印其中出现次数大于一半的数,如果没有这样的数,打印提示信息
进阶:给定一个整型数组arr,再给定一个整数K,打印所有出现次数大于N/K的数,如果没有这样的数,打印提示信息。
要求:原问题时间复杂度为O(N),额外空间复杂度为O(1)。进阶问题时间复杂度要求为O(N×K),额外空间复杂度为O(K)。
代码
根据书中java代码实现了原问题和进阶问题。
#include<iostream>
#include<algorithm>
#include<map>
#include<list>
using namespace std;
void printHalfMajor(int* arr, int len)
{
int cand = 0;
int times = 0;
for (int i = 0; i < len; i++)
{
if (times == 0)
{
cand = arr[i];
times = 1;
}
else if (arr[i] == cand)
times++;
else
times--;
}
times = 0;
for (int i = 0; i < len; i++)
{
if (arr[i] == cand)
times++;
}
if (times > len / 2)
cout << cand << endl;
else
cout << "No such Number!" << endl;
}//阵地攻守or删除数组中相同两个数()
map<int, int> getReals(int* arr, int len, map<int, int>cands)
{
map<int, int> reals;
for (int i = 0; i < len; i++)
{
int curNum = arr[i];
if (cands.find(curNum) != cands.end())
{
if (reals.find(curNum) != reals.end())
reals[curNum] = reals[curNum] + 1;
else
reals[curNum] = 1;
}
}
return reals;
}
void allCandsMinusOne(map<int, int> &m)
{
list<int> removeList;
map<int, int>::iterator it;
list<int>::iterator itList = removeList.begin();
for (it = m.begin(); it != m.end(); it++)
{
int key = it->first;
int value = it->second;
if (value == 1)
{
removeList.push_back(key);
}
m[key] = value - 1;
}
list<int>::iterator it1;
map<int, int>::iterator del1;
int value = 0;
for (it1 = removeList.begin(); it1 != removeList.end(); it1++)
{
value = *it1;
del1 = m.find(value);
m.erase(del1);
}
}
void printKMajor(int* arr, int k, int len)
{
if (k < 2)
{
cout << "The value of K is invalie." << endl;
return;
}
map<int, int>cands;
for (int i = 0; i < len; i++)
{
if (cands.find(arr[i]) != cands.end())
cands[arr[i]] = cands[arr[i]] + 1;
else
{
if (cands.size() == k - 1)
allCandsMinusOne(cands);
else
cands[arr[i]] = 1;
}
}
map<int, int> reals = getReals(arr, len, cands);
bool hasPrint = false;
map<int, int>::iterator it;
for (it = cands.begin(); it != cands.end(); it++)
{
int key = it->first;
if (reals[key] > len / k)
{
hasPrint = true;
cout << key << " ";
}
}
cout << (hasPrint ? "" : "No such Number.") << endl;
}
int main()
{
int len, k;
cin >> len >> k;
int* in = new int[len];
for (int i = 0; i < len; i++)
cin >> in[i];
//printHalfMajor(in, len);
printKMajor(in, k, len);
getchar();
return 0;
}
在行列都排好序的矩阵中找数
题目
给定一个有N×M的整型矩阵matrix和一个整数K,matrix的每一行和每一列都是排好序的。实现一个函数,判断K是否在matrix中。
代码
题目比较简单,见过几次了,从左下角开始搜索即可。可以达到*O(M+N)*时间复杂度
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
bool findNum(vector<vector<int>> in, int k)
{
int row = in.size();
int col = in[0].size();
int i = row - 1;
int j = 0;
bool res = false;
while (i >= 0 && j <= col - 1)
{
if (in[i][j] < k)
j++;
else if (in[i][j] > k)
i--;
else
{
res = true;
break;
}
}
return res;
}
int main()
{
int m, n, k;
cin >> m >> n >> k;
vector<vector<int>> in(m, vector<int>(n, 0));
for (int i = 0; i < m; i++)
{
for (int j = 0; j < n; j++)
cin >> in[i][j];
}
bool res = findNum(in, k);
if (res)
cout << "true" << endl;
else
cout << "false" << endl;
getchar();
return 0;
}
发现自己思路一点都不活跃,本来就是刷题纯刷来的,可是一道简单题就能别自己好久,一天下来也刷不了几道题,果然还是菜鸡,一点疑问都没有。