PAT Grade A Question Record-(AcWing)-(Day06 Tree 8 Questions)

PAT Grade A Question Record-(AcWing)-(Day06 Tree 8 Questions)

The course comes from AcWing,
where the titles in AcWing are translated Chinese titles

Today's list of questions

  • 1110 Complete Binary Tree
  • 1115 Counting Nodes in a Binary Search Tree
  • 1119 Pre- and Post-order Traversals
  • 1127 ZigZagging on a Tree
  • 1138 Postal Order Traversal
  • 1066 Root of AVL Tree
  • 1123 Is It a Complete AVL Tree
  • 1135 Is It A Red-Black Tree

1110 Complete Binary Tree

AcWing link
PAT link

important point

  • At the beginning, when I read in the nodes, I used charand a-'0'to store, because I didn’t see that there might be 10a node number greater than that in the title, and then I changed it stringto
  • stoi()It is very convenient to stringconvert the string of type toint
#include <iostream>
#include <cstring>
#include <algorithm>

const int N = 30;
using namespace std;
int l[N], r[N];
int n, last_idx, last_node, root = 0;
bool is_father[N];

void dfs(int u, int k) {
    
    
    // u代表当前节点,k代表完全二叉树中的节点
    if (u == -1) return;
    if (k > last_idx) {
    
    
        last_idx = k;
        last_node = u;
    }
    dfs(l[u], 2 * k);
    dfs(r[u], 2 * k + 1);
}

int main() {
    
    
    cin >> n;
    memset(l, -1, sizeof(l));
    memset(r, -1, sizeof(r));
    for (int i = 0; i < n; ++i) {
    
    
        string a, b;
        cin >> a >> b;
        if (a != "-") l[i] = stoi(a), is_father[l[i]] = true;
        if (b != "-") r[i] = stoi(b), is_father[r[i]] = true;
    }
    while (is_father[root]) root++;
    dfs(root, 1);
    if (last_idx == n) cout << "YES " << last_node;
    else cout << "NO " << root;
    return 0;
}

1115 Counting Nodes in a Binary Search Tree

AcWing link
PAT link

important point

  • This is used when inserting , you can update the value &upassed in at the beginning , or you can change the value in the recursion laterrootl[u],r[u]
#include <iostream>
#include <cstring>

using namespace std;
const int N = 1010;
int l[N], r[N], val[N], idx = 0;
int cnt[N];
int max_depth;

void insert(int &u, int w) {
    
    
    if (u == 0) {
    
    
        u = ++idx;
        cout << "u = " << u << endl;
        val[u] = w;
    } else if (w <= val[u]) insert(l[u], w);
    else insert(r[u], w);
}

void dfs(int root, int depth) {
    
    
    if (root == 0) return;
    max_depth = max(depth, max_depth);
    cnt[depth]++;
    dfs(l[root], depth + 1);
    dfs(r[root], depth + 1);
}

int main() {
    
    
    int n;
    cin >> n;
    int root = 0;
    for (int i = 0; i < n; ++i) {
    
    
        int x;
        cin >> x;
        insert(root, x);
        cout << root << endl;
        cout << "*****************" << endl;
    }
    dfs(root, 0);
    int n1 = cnt[max_depth];
    int n2 = cnt[max_depth - 1];
    printf("%d + %d = %d\n", n1, n2, n1 + n2);
    return 0;
}

!!! 1119 Pre- and Post-order Traversals

AcWing link
PAT link

English words

The difficulty of parsing
lies in the sequence of recursive and violent traversal preorder traversal, and finding the left and right dividing points.

#include <cstring>
#include <iostream>

const int N = 40;
using namespace std;
int pre[N], post[N];

int dfs(int prel, int prer, int postl, int postr, string &s) {
    
    
    if (prel > prer) return 1;
    if (pre[prel] != post[postr]) return 0;
    int cnt = 0;
    for (int i = prel; i <= prer; ++i) {
    
    
        string lin, rin;
        int lcnt = dfs(prel + 1, i, postl, postl + i - prel - 1, lin);
        int rcnt = dfs(i + 1, prer, postl + i - prel, postr - 1, rin);
        if (lcnt && rcnt) {
    
    
            s = lin + to_string(pre[prel]) + " " + rin;
            cnt += lcnt * rcnt;
            if (cnt > 1)break;
        }
    }
    return cnt;
}

int main() {
    
    
    int n;
    cin >> n;
    for (int i = 0; i < n; ++i) {
    
    
        cin >> pre[i];
    }
    for (int i = 0; i < n; ++i) {
    
    
        cin >> post[i];
    }
    string res;
    int cnt = dfs(0, n - 1, 0, n - 1, res);
    if (cnt == 1) puts("Yes");
    else puts("No");
    res.pop_back();
    puts(res.c_str());
    return 0;
}

1127 ZigZagging on a Tree

AcWing link
PAT link

English words

  • naive naive
  • alternating Alternate, interactive
    analysis
    is similar to question 1020, except that this question needs to be reversed according to the number of layers to record the current traversal sequence when traversing the layer sequence.
    Note that the key
    l.count(t) is the number of keys lin the hash table t, if it exists, l[t]add it to the queue
#include <cstring>
#include <iostream>
#include <unordered_map>
#include <algorithm>

const int N = 40;
using namespace std;
unordered_map<int, int> l, r, pos;
int inorder[N], post[N];
int q[N];
int n;

int build(int il, int ir, int pl, int pr) {
    
    
    int root = post[pr];
    int k = pos[root];
    if (il < k) l[root] = build(il, k - 1, pl, pl + k - 1 - il);
    if (k < ir) r[root] = build(k + 1, ir, pl + k - il, pr - 1);
    return root;
}

void bfs(int root) {
    
    
    q[0] = root;
    int head = 0, tail = 0;
    int step = 0;
    while (head <= tail) {
    
    
        int cur_head = head, cur_tail = tail;
        while (head <= cur_tail) {
    
    
            int t = q[head++];
            if (l.count(t)) q[++tail] = l[t];
            if (r.count(t)) q[++tail] = r[t];
        }
        if (++step % 2 == 1) reverse(q + cur_head, q + cur_tail + 1);
    }
    cout << q[0];
    for (int i = 1; i < n; ++i) {
    
    
        cout << " " << q[i];
    }
}

int main() {
    
    
    cin >> n;
    for (int i = 0; i < n; ++i) cin >> inorder[i], pos[inorder[i]] = i;
    for (int i = 0; i < n; ++i) cin >> post[i];
    int root = build(0, n - 1, 0, n - 1);
    bfs(root);
    return 0;
}

1138 Postal Order Traversal

AcWing link
PAT link

important point

Without using the hash table writing method, the test point can be passed, but the test point 4 took 341 ms

#include <iostream>

const int N = 50010;
using namespace std;
int pre[N], in[N];
int l[N], r[N];
int n;
int post = 0, flag = 1;

void build(int il, int ir, int pl, int pr) {
    
    
    if (flag == 0) return;
    int root = pre[pl];
    int k;
    for (int i = il; i <= ir; ++i) {
    
    
        if (in[i] == root) {
    
    
            k = i;
            break;
        }
    }
    if (il < k) build(il, k - 1, pl + 1, pl + 1 + k - 1 - il);
    if (k < ir) build(k + 1, ir, pl + 1 + k - 1 - il + 1, pr);
    if (post == 0) {
    
    
        post = root;
        cout << post;
        flag = 0;
        return;
    }
}

int main() {
    
    
    cin >> n;
    for (int i = 0; i < n; ++i)cin >> pre[i];
    for (int i = 0; i < n; ++i)cin >> in[i];
    build(0, n - 1, 0, n - 1);
    return 0;
}

Using the writing method of the hash table, the test point 4 only took 34 ms

#include <iostream>
#include <unordered_map>

const int N = 50010;
using namespace std;
int pre[N], in[N];
unordered_map<int, int> l, r, pos;
int n;
int post = 0, flag = 1;

void build(int il, int ir, int pl, int pr) {
    
    
    if (flag == 0) return;
    int root = pre[pl];
    int k = pos[root];
    if (il < k) build(il, k - 1, pl + 1, pl + 1 + k - 1 - il);
    if (k < ir) build(k + 1, ir, pl + 1 + k - 1 - il + 1, pr);
    if (post == 0) {
    
    
        post = root;
        cout << post;
        flag = 0;
        return;
    }
}

int main() {
    
    
    cin >> n;
    for (int i = 0; i < n; ++i)cin >> pre[i];
    for (int i = 0; i < n; ++i)cin >> in[i], pos[in[i]] = i;
    build(0, n - 1, 0, n - 1);
    return 0;
}

1066 Root of AVL Tree

AcWing link
PAT link

English words

  • differ by difference

Analysis
In the figure below, I have drawn the right-handed process of the binary tree, just reverse the left-handed
insert image description here

important point

  • height_differ(r[u]) == -1When calculating whether the right subtree should be left-handed or not, one sum was wrongly written, rand lI searched for a long timebug
  • The main test point is whether it should be rotated or not, just understand the above picture
#include <iostream>

const int N = 30;
using namespace std;
int l[N], r[N], v[N], h[N], idx;

void update(int u) {
    
    
    h[u] = max(h[l[u]], h[r[u]]) + 1;
}

void R(int &u) {
    
    // 右旋
    int p = l[u];
    l[u] = r[p];
    r[p] = u;
    update(u);
    update(p);
    u = p;
}

void L(int &u) {
    
    
    int p = r[u];
    r[u] = l[p];
    l[p] = u;
    update(u);
    update(p);
    u = p;
}

int height_differ(int u) {
    
    
    // 计算左右子树的差
    return h[l[u]] - h[r[u]];
}


void insert(int &u, int w) {
    
    
    if (!u) {
    
    
        u = ++idx;
        v[u] = w;
    } else if (w < v[u]) {
    
    
        // 插入左子树
        insert(l[u], w);
        // 检查是否要旋
        if (height_differ(u) == 2) {
    
    
            // 插入左子树之后可能造成左子树高度多一些
            if (height_differ(l[u]) == 1) {
    
    
                // 左子树的左子树高于右子树, 直接右旋即可
                R(u);
            } else {
    
    
                // 左子树的右子树高于左子树的左子树,先左旋再右旋
                L(l[u]);
                R(u);
            }
        }
    } else {
    
    
        // 插入右子树
        insert(r[u], w);
        // 检查是否要旋
        if (height_differ(u) == -2) {
    
    
            // 插入右子树之后可能造成右子树高度多一些
            if (height_differ(r[u]) == -1) {
    
    
                // 右子树的右子树高于左子树, 直接左旋即可
                L(u);
            } else {
    
    
                // 右子树的左子树高于右子树的右子树,先右旋再左旋
                R(r[u]);
                L(u);
            }
        }
    }
    update(u);
}

int main() {
    
    
    int n, root = 0;
    cin >> n;
    for (int i = 0; i < n; ++i) {
    
    
        int w;
        cin >> w;
        insert(root, w);
    }
    cout << v[root] << endl;
    return 0;
}

1123 Is It a Complete AVL Tree

AcWing link
PAT link

analyze

  • Comprehensive basic questions, in which the process of building a balanced binary tree is exactly the same as the previous question
  • In the process of implementing hierarchical traversal, use posto record the subscripts of each node (or their parent node 两倍) 两倍+1to determine whether the following table exceeds n, if the subscripts of n nodes do not exceed n, then it must be a complete binary tree .
#include <iostream>
#include <algorithm>
#include <cstring>
#include <unordered_map>


const int N = 30;
using namespace std;
int n;
int l[N], r[N], v[N], h[N], idx;
int q[N], pos[N];

void update(int u) {
    
    
    h[u] = max(h[l[u]], h[r[u]]) + 1;
}

void L(int &u) {
    
    
    // 左旋
    int p = r[u];
    r[u] = l[p];
    l[p] = u;
    update(u);
    update(p);
    u = p;
}

void R(int &u) {
    
    
    // 左旋
    int p = l[u];
    l[u] = r[p];
    r[p] = u;
    update(u);
    update(p);
    u = p;
}

int differ_height(int u) {
    
    
    // 返回左右子树高度差
    return h[l[u]] - h[r[u]];
}

void insert(int &u, int w) {
    
    
    if (!u) {
    
    
        u = ++idx;
        v[u] = w;
    } else if (w < v[u]) {
    
    
        //插入左
        insert(l[u], w);
        if (differ_height(u) == 2) {
    
    
            if (differ_height(l[u]) == 1) R(u);
            else L(l[u]), R(u);
        }
    } else {
    
    
        insert(r[u], w);
        if (differ_height(u) == -2) {
    
    
            if (differ_height(r[u]) == -1) L(u);
            else R(r[u]), L(u);
        }
    }
    update(u);
}

bool bfs(int root) {
    
    
    q[0] = root;
    int k = 1;
    pos[root] = 1;
    int head = 0, tail = 0;
    while (head <= tail) {
    
    
        int t = q[head++];
        if (pos[t] > n) return false;
        if (l[t]) q[++tail] = l[t], pos[l[t]] = 2 * pos[t];
        if (r[t]) q[++tail] = r[t], pos[r[t]] = 2 * pos[t] + 1;
    }

    return true;
}

int main() {
    
    
    cin >> n;
    memset(h, -1, sizeof(h));
    int root = 0;
    for (int i = 0; i < n; ++i) {
    
    
        int w;
        cin >> w;
        insert(root, w);
    }
    bool res = bfs(root);
    cout << v[q[0]];
    for (int i = 1; i < n; ++i) {
    
    
        cout << ' ' << v[q[i]];
    }
    cout << endl;
    if (res) cout << "YES" << endl;
    else cout << "NO" << endl;
    return 0;
}

!!! 1135 Is It A Red-Black Tree

AcWing link
PAT link

English words

  • simple paths simple paths
  • descendant leaves descendant node

important point

  • In the process of building a balanced binary tree to determine whether it is a red-black tree
#include <iostream>
#include <algorithm>
#include <unordered_map>

const int N = 40;
using namespace std;
int n, k;
int pre[N], in[N];
unordered_map<int, int> pos;
bool res;


int build(int il, int ir, int pl, int pr, int &sum) {
    
    
    int root = pre[pl];
    int index = pos[abs(root)];
    if (index > ir || index < il) {
    
    
        res = false;
        return 0;
    }
    int left = 0, right = 0, left_sum = 0, right_sum = 0;
    if (il < index) left = build(il, index - 1, pl + 1, pl + 1 + index - 1 - il, left_sum);
    if (index < ir) right = build(index + 1, ir, pl + 1 + index - 1 - il + 1, pr, right_sum);
    if (left_sum != right_sum) res = false;
    sum = left_sum;
    if (root < 0) {
    
    
        if (left < 0 || right < 0) res = false;
    } else sum++;
    return root;
}

int main() {
    
    
    cin >> k;
    while (k--) {
    
    
        cin >> n;
        for (int i = 0; i < n; ++i) {
    
    
            cin >> pre[i];
            in[i] = abs(pre[i]);
        }
        sort(in, in + n);
        pos.clear();
        for (int i = 0; i < n; ++i) {
    
    
            pos[in[i]] = i;
        }
        res = true;
        int sum = 0;
        int root = build(0, n - 1, 0, n - 1, sum);
        if (root < 0) res = false;
        if (res) puts("Yes");
        else puts("No");
    }
    return 0;
}

template

AcWing link
PAT link

English words

analyze

important point


Guess you like

Origin blog.csdn.net/Weary_PJ/article/details/124887235