今日:刷题真痛苦
八皇后
求逆序数
树的字段和
上代码
/**
* 八皇后问题,初始化,放,递归搜索
*/
/**
* 初始化一个 queen,mark 表示一个棋盘 N*N,location 表示一个queen的点状图,result 存储最终结果
* [".Q..", location是这种点阵表达的,一个状态.初始都是"."
"...Q",
"Q...",
"..Q."]
*
* ["1110", mark 表示棋盘,初始都是0
"1111",
"1110",
"0101"]
* 初始化一组皇后数据
*/
std::vector<std::vector<string>> getQueen(int n) {
std::vector<std::vector<string>> result;
std::vector<string> location;
std::vector<std::vector<int>> mark;
for (int i = 0; i < n; i++)
{
mark.push_back((std::vector<int> ()));
for (int j = 0; j < n; j++)
{
mark[i][j] = 0;
}
string temp(n,".");
location.push_back(temp);
}
generateQueen(0, n, location, mark, result);
}
/**
* 放置皇后,同时更新棋盘,前后左右中斜都要置1
* 八个坐标位置(x,y)是 queen,下面用dx,dy来表示对应的x,y 坐标移动,对应的下标里面的值就是 X与 Y 想加的值
(x-1,y-1) (x-1,y) (x-1,y+1)
(x,y-1) (x,y) (x,y+1)
(x+1,y-1) (x+1,y) (x+1,y+1)
*/
void putQueen(int x, int y, std::vector<std::vector<int>> &mark) {
static const int dx[] = {-1,-1,-1, 0, 0, 1, 1, 1};
static const int dy[] = {-1, 0, 1,-1, 1,-1, 0, 1};
mark[x][y] = 1;
//每一行都向皇后周围八个方向扩展置1
for (int k = 1; k < mark.size(); k++) {
for (int j = 0; j < 8; j++) {
int newX = x + i*dx[j];
int newY = y + i*dy[j];
if (newX>=0 && newX < mark.size() && newY >=0 && newY < mark.size()) {
mark[newX][newY] = 1;
}
}
}
}
/**
* 递归放置棋盘,i 标识行号,n 是列,mark 标识棋盘状态,result 最终结果数组 N行 N 列的8皇后
*
*/
void generateQueen(int i, int n, std::vector<string> &location, std::vector<std::vector<int>> &mark, std::vector<std::vector<string>> &result) {
//i放到最后一行了,就返回当前location
if (i == n) {
result.push_back(location);
return;
}
//循环 n 列
for (int k = 0; k < n; k++) {
//当前可以放 QUEEN
if (mark[i][k] == 0) {
std::vector<std::vector<int>> temp_mark = mark;
location[i][k] = 'Q';
putQueen(i,k,mark);
generateQueen(i+1, k, location, mark, result);
location[i][k] = '.';
mark = temp_mark;
}
}
}
/**
* 逆序数,计算右侧小于当前元素的个数,归并排序
*/
vector<int> countSmaller(vector<int>& nums) {
std::vector<int> result;
std::vector<pair<int, int>> vec;
for (int i=0;i<nums.size();i++) {
vec.push_back(make_pair(nums[i], i));
}
}
//归并
void merge_sort(std::vector<pair<int,int>> &vec, std::vector<int> &result) {
if (vec.size() < 2) {
return;
}
int mid = vec.size();
std::vector<pair<int, int>> vec1;
std::vector<pair<int, int>> vec2;
for (int i = 0; i < mid; i++)
{
vec1.push_back(vec[i]);
}
for (int i = mid; i < vec.size(); i++)
{
vec2.push_back(nums[i]);
}
merge_sort(vec1, result);
merge_sort(vec2, result);
vec.clear();
merge_two_arr(vec1, vec2, vec, result);
}
//排序
void merge_two_arr(std::vector<pair<int,int>> &vec1, std::vector<pair<int, int>> &vec2, std::vector<int> &vec, std::vector<int> &result) {
int i=0;
int j=0;
while(i < vec1.size() && j < vec2.size()) {
if(vec1[i].first < vec2[j].first) {
result[vec1[i].second] += j;
vec.push_back(vec1);
i++;
} else {
vec.push_back(vec2[j]);
j++;
}
}
for (;i < vec1.size(); i++)
{
result[vec1[i].second] += j;
vec.push_back(vec1);
}
for (;j < vec2.size(); j++)
{
vec.push_back(vec1);
}
}
树,双次递归,因为任意一个节点都可能是路径的头结点
/**
* 树的路径和,给你一个key,求和等于key的路径,不一定是头或者尾节点
*/
int count = 0;
int getCount(BTree root, int key) {
if (!root)
{
reutrn 0;
}
return count;
}
void solve(BTree root, int key) {
if(!root) {
return;
}
//先看看 root 节点为起始的序列中有没有
dfs(root,key);
//再分别以左右儿子为起点继续找
solve(root->left, key);
solve(root->right, key);
}
void dfs(BTree root, int sum) {
if (!root) {
return;
}
sum -= root->val;
if (sum == 0) {
count++;
}
dfs(root->left, sum);
dfs(root->right, sum);
}