day3 牛客TOP100:BM 21-30 二分法 二叉树

news2024/11/30 14:50:11

文章目录

  • 二分法
    • BM21 旋转数组的最小数字
    • BM22 比较版本号
    • 力扣-旋转数组的查找
    • 力扣-两个非空链表逆序相加
  • 二叉树
    • BM23 二叉树的前序遍历
    • BM24 二叉树的中序遍历
    • BM25 二叉树的后序遍历
    • BM26 求二叉树的层序遍历
    • BM27 按之字形顺序打印二叉树
    • BM28 二叉树的最大深度
    • BM29 二叉树中和为某一值的路径(一)
    • BM30 二叉搜索树与双向链表

二分法

BM21 旋转数组的最小数字

在这里插入图片描述

#include <climits>
class Solution {
public:
    int minNumberInRotateArray(vector<int>& nums) {
        if(nums.size() <= 0) return 0;
        int left=0, right=nums.size()-1;
        while(left <= right)
        {
            int mid = left + (right - left) / 2;
            if(nums[mid] > nums[right])//右边是降序 最小的数字在mid右边
                left = mid+1;
            else if(nums[mid] < nums[right])//右边是升序 最小数字要么是mid(奇数个数字) 要么在mid左边(偶数个)
                right = mid;
            else right--;//无法判断,一个一个试
        }
        return nums[left];
    }
};

BM22 比较版本号

在这里插入图片描述
看解答写的,两个指针依次遍历两个字符串,分为字符处理与比较两部分:
首先把小数点之前的字符转化为数字,跳过当前小数点,处理两个字符串;
然后得到的数字。

class Solution {
public:
    int compare(string version1, string version2) {
        int res = 0;
        int v1 = 0, v2 = 0;
        long long num1 = 0, num2 = 0;
        while(v1<version1.size() || v2<version2.size())
        {
            num1 = 0;
            //截取最近一个小数点之前的数字
            while(v1 < version1.size() && version1[v1] != '.')
            {
                num1 = num1 * 10 + version1[v1] - '0';
                v1++;
            }
            //跳过该小数点
            v1++;
            //相同的处理
            num2 = 0;
            while(v2 < version2.size() && version2[v2] != '.')
            {
                num2 = num2 * 10 + version2[v2] - '0';
                v2++;
            }
            v2++;
            //比较数字
            if(num1 > num2) return 1;
            if(num1 < num2) return -1;
        }
        return 0;
    }
};

一开始自己想的就是这种办法,使用流输入istringstream来分割:

  • 使用字符串流输入,按照点将两个原始字符串分割,使每个修订号的数字单独呈现在数组中;
  • 遍历数组,每次各自取出一个数字比较,较短的版本号没有可取的数字了,就直接取0;
  • 遍历取出的数字字符串,将其转换成数字,比较数字大小,根据大小关系返回值。如果全部比较完都无法比较出大小关系,则返回0。

这种解法要学习的一个是流输入的使用,一个是较短版本号的处理

#include <sstream>
class Solution {
  public:
    int compare(string version1, string version2) {
        //使用流输入istringstream
        vector<string> num1;
        vector<string> num2;
        istringstream ss1(version1);
        istringstream ss2(version2);

        string temp;
        //流输入分割
        while(getline(ss1, temp, '.'))
            num1.push_back(temp);
        while(getline(ss2, temp,'.'))
            num2.push_back(temp);
        
        //字符串转数字 比较
        for(int i=0; i<num1.size() || i<num2.size(); i++)
        {
            //较短的版本号取0 这个处理很好
            string s1 = i < num1.size() ? num1[i] : "0";
            string s2 = i < num2.size() ? num2[i] : "0";
            long long num1 = 0, num2 = 0;
            for(int j = 0; j<s1.size(); j++)
                num1 = num1 * 10 + s1[j] - '0';
            for(int j=0; j<s2.size(); j++)
                num2 = num2 * 10 + s2[j] - '0';
            //比较数字
            if(num1 > num2) return 1;
            if(num1 < num2) return -1;
        }
        return 0;
    }
};

力扣-旋转数组的查找

在这里插入图片描述
二分里边再次二分

class Solution {
public:
    int search(vector<int>& nums, int target) {
        int left = 0, right = nums.size()-1;
        int mid = 0, index = 0;
        while(left <= right)
        {
            mid = left + (right - left) / 2;
            if(nums[mid] == target) return mid;
            //先看mid 在左边还是右边 先根据 nums[mid] 与 nums[lo] 的关系判断 mid 是在左段还是右段 
            if(nums[left] <= nums[mid])//mid在左边
            {
                //再看target在mid的左边还是右边  再判断 target 是在 mid 的左边还是右边,从而调整左右边界 lo 和 hi
                if(target >= nums[left] && target < nums[mid])//在左边 后半段不能取等号
                {
                    right = mid-1;
                }
                else left = mid+1;
            }
            else//nums[left] > nums[mid]
            {
                if(target > nums[mid] && target <= nums[right])//在mid右边
                    left = mid+1;
                else right = mid-1;
            }
        }
        return -1;
    }
};

力扣-两个非空链表逆序相加

在这里插入图片描述

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
        //if(l1->val==0 && l2->val==0) return l1;
        ListNode* dummyhead = new ListNode(0);
        ListNode* cur = dummyhead;
        int flag = 0;
        int val1 = 0, val2 = 0, sum = 0;
        while(l1!=nullptr || l2!=nullptr)
        {
            //数字处理部分
            val1 = (l1 == nullptr) ? 0 : l1->val;
            val2 = (l2 == nullptr) ? 0 : l2->val;
            sum = val1 + val2 + flag;
            flag = sum / 10;//进位不加判断 直接取整数 大于等于10取1,否则取0
            sum  = sum % 10;//取余数
            
            //cout << "l1:" << val1 << "  l2:" << val2 << endl;
            //cout << "sum:" << sum << "  flag:" << flag << endl;

            cur->next = new ListNode(sum);//指向新结点,连接链表
            
            //节点更新
            cur = cur->next;
            if(l1 != nullptr) l1 = l1->next;
            if(l2 != nullptr) l2 = l2->next;
        }
        //如果还有进位的话要加上 最高位 如测试用例3
        if(flag == 1) cur->next = new ListNode(flag);
        return dummyhead->next;
    }
};

二叉树

BM23 二叉树的前序遍历

描述:给你二叉树的根节点 root ,返回它节点值的 前序 遍历。

  • 递归法很简单
/**
 * struct TreeNode {
 *	int val;
 *	struct TreeNode *left;
 *	struct TreeNode *right;
 *	TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 * };
 */
#include <vector>
class Solution {
public:
    vector<int> res;
    vector<int> preorderTraversal(TreeNode* root) {
        res.clear();
        if(root == nullptr) return res;
        //递归
        dfs(root);
        return res;
    }
    void dfs(TreeNode* root)
    {
        if(root == nullptr)
            return;
        res.push_back(root->val);
        dfs(root->left);
        dfs(root->right);
    }
};
  • 迭代法,用辅助栈,入栈顺序是右左中
/**
 * struct TreeNode {
 *	int val;
 *	struct TreeNode *left;
 *	struct TreeNode *right;
 *	TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 * };
 */
#include <vector>
class Solution {
public:
    vector<int> res;
    vector<int> preorderTraversal(TreeNode* root) {
        res.clear();
        if(root == nullptr) return res;
        //迭代
        stack<TreeNode*> st;
        st.push(root);
        TreeNode* temp;
        while(!st.empty())
        {
            //访问栈顶
            temp = st.top();
            st.pop();
            res.push_back(temp->val);
            //前序 中左右 栈 先进后出 入栈 右左中
            if(temp->right) st.push(temp->right);
            if(temp->left) st.push(temp->left); 
        }
        return res;
    }
};
  • 统一迭代法
/**
 * struct TreeNode {
 *	int val;
 *	struct TreeNode *left;
 *	struct TreeNode *right;
 *	TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 * };
 */
#include <vector>
class Solution {
public:
    vector<int> res;
    vector<int> preorderTraversal(TreeNode* root) {
        res.clear();
        if(root == nullptr) return res;
        //统一迭代法
        bfs(root);
        return res;
    }
    //统一迭代法
    void bfs(TreeNode* root)
    {
        if(root == nullptr)
            return;
        stack<TreeNode*> st;
        st.push(root);
        TreeNode* temp;
        while(!st.empty())
        {
            temp = st.top();
            if(temp != nullptr)
            {
                st.pop();
                if(temp->right) st.push(temp->right);
                if(temp->left) st.push(temp->left);
                st.push(temp);
                st.push(nullptr);//当前层结束
            }
            else {
                st.pop();
                temp = st.top();
                st.pop();
                res.push_back(temp->val);
            }
        }
    }
};

BM24 二叉树的中序遍历

描述:给定一个二叉树的根节点root,返回它的中序遍历结果。进阶:空间复杂度 O(n),时间复杂度 O(n)。

  • 统一迭代法,关键就是在中结点后面加一个空节点标记
/**
 * struct TreeNode {
 *	int val;
 *	struct TreeNode *left;
 *	struct TreeNode *right;
 *	TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 * };
 */
class Solution {
public:
    vector<int> result;
    vector<int> inorderTraversal(TreeNode* root) {
        result.clear();
        if(root == nullptr) return result;
        unitedbfs(root);
        return result;
    }
    void unitedbfs(TreeNode* root)
    {
        if(root == nullptr) return;
        stack<TreeNode*> st;
        st.push(root);
        TreeNode* temp;
        while(!st.empty())
        {
            temp = st.top();
            st.pop();
            if(temp != nullptr)
            {
                if(temp->right) st.push(temp->right);
                st.push(temp);
                st.push(nullptr);
                if(temp->left) st.push(temp->left);
                
            }
            else 
            {
                //更新当前节点
                temp = st.top();
                st.pop();
                result.push_back(temp->val);
            }
        }
    }
};
  • 递归法
/**
 * struct TreeNode {
 *	int val;
 *	struct TreeNode *left;
 *	struct TreeNode *right;
 *	TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 * };
 */
class Solution {
public:
    vector<int> result;
    vector<int> inorderTraversal(TreeNode* root) {
        result.clear();
        if(root == nullptr) return result;
        dfs(root);
        return result;
    }
    void dfs(TreeNode* root)
    {
        if(root == nullptr) return;
        if(root->left) dfs(root->left);
        result.push_back(root->val);
        if(root->right) dfs(root->right);
    }
};

BM25 二叉树的后序遍历

描述:给定一个二叉树,返回他的后序遍历的序列。后序遍历是值按照 左节点->右节点->根节点 的顺序的遍历。

  • 统一迭代法
/**
 * struct TreeNode {
 *	int val;
 *	struct TreeNode *left;
 *	struct TreeNode *right;
 *	TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 * };
 */
class Solution {
public:
    vector<int> result;
    vector<int> postorderTraversal(TreeNode* root) {
        result.clear();
        if(root == nullptr) return result;
        //dfs(root);
        unitedbfs(root);
        return result;
    }
    void unitedbfs(TreeNode* root)
    {
        stack<TreeNode*> st;
        if(root != nullptr) st.push(root);
        TreeNode* temp;
        while(!st.empty())
        {
            temp = st.top();
            st.pop();
            if(temp != nullptr)
            {
                st.push(temp);
                st.push(nullptr);
                if(temp->right) st.push(temp->right);
                if(temp->left) st.push(temp->left);
            }
            else {
                temp = st.top();
                st.pop();
                result.push_back(temp->val);
            }
        }
    }
    void dfs(TreeNode* root)
    {
        if(root == nullptr) return;
        if(root->left) dfs(root->left);
        if(root->right) dfs(root->right);
        result.push_back(root->val);
    }
};
  • 递归法
/**
 * struct TreeNode {
 *	int val;
 *	struct TreeNode *left;
 *	struct TreeNode *right;
 *	TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 * };
 */
class Solution {
public:
    vector<int> result;
    vector<int> postorderTraversal(TreeNode* root) {
        result.clear();
        if(root == nullptr) return result;
        dfs(root);
        return result;
    }
    void dfs(TreeNode* root)
    {
        if(root == nullptr) return;
        if(root->left) dfs(root->left);
        if(root->right) dfs(root->right);
        result.push_back(root->val);
    }
};

BM26 求二叉树的层序遍历

在这里插入图片描述

  • 迭代法
    和上面三个题不一样的地方来了,这里的层序遍历用队列。队列存放当前层的结点,for循环逐个遍历队列,每一层通过队列的大小(节点个数)来控制。
/**
 * struct TreeNode {
 *	int val;
 *	struct TreeNode *left;
 *	struct TreeNode *right;
 *	TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 * };
 */
class Solution {
public:
    vector<vector<int> > result;
    vector<vector<int> > levelOrder(TreeNode* root) {
        result.clear();
        if(root == nullptr) return result;
        queue<TreeNode* > que;
        que.push(root);
        TreeNode* cur;
        int size = 0;
        while(!que.empty())
        {
            vector<int> temp;
            size = que.size();
            for(int i=0; i<size; i++)
            {
                cur = que.front();
                que.pop();
                temp.push_back(cur->val);
                if(cur->left) que.push(cur->left);
                if(cur->right) que.push(cur->right);
            }
            result.push_back(temp);
        }
        return result;
    }
};
  • 递归法,通过深度来控制
/**
 * struct TreeNode {
 *	int val;
 *	struct TreeNode *left;
 *	struct TreeNode *right;
 *	TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 * };
 */
class Solution {
public:
    vector<vector<int> > result;
    vector<vector<int> > levelOrder(TreeNode* root) {
        result.clear();
        if(root == nullptr) return result;
        int depth = 0;
        dfs(root, depth);
        return result;
    }
    void dfs(TreeNode* root, int depth)
    {
        if(root == nullptr) return;
        if(result.size() == depth) result.push_back(vector<int>{});
        result[depth].push_back(root->val);
        if(root->left) dfs(root->left, depth+1);
        if(root->right) dfs(root->right, depth+1);
    }
};

BM27 按之字形顺序打印二叉树

  • 栈实现,两个栈,一个保存从左到右的结点,一个保存从右到左的节点。处理每个栈的时候有点层序遍历的意思,遍历当前栈的所有节点,同时把下一层的结点保存在另外一个栈中。可以用for或者while实现。
/**
 * struct TreeNode {
 *	int val;
 *	struct TreeNode *left;
 *	struct TreeNode *right;
 *	TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 * };
 */
#include <iterator>
#include <ratio>
#include <stack>
class Solution {
public:
    vector<vector<int> > result;
    vector<vector<int> > Print(TreeNode* pRoot) {
        result.clear();
        if(pRoot == nullptr) return result;
        stackdone(pRoot);
        return result;
    }
    void stackdone(TreeNode* node)
    {
        stack<TreeNode*> st1;
        stack<TreeNode*> st2;
        vector<int> v;
        TreeNode* cur;
        if(node != nullptr) st1.push(node);
        while(!st1.empty() || !st2.empty())
        {
            if(!st1.empty())
            {
                //左到右
                v.clear();
                int size = st1.size();
                for(int i=0; i<size; i++)
                {
                    cur = st1.top();//当前结点
                    v.push_back(cur->val);//保存当前结点值
                    //栈 先进后出 下一层在st2 入栈顺序是左 右;出栈就是右 左
                    if(cur->left) st2.push(cur->left);
                    if(cur->right) st2.push(cur->right);
                    st1.pop();
                }
                result.push_back(v);
            }
            if(!st2.empty())
            {
                //从右到左
                v.clear();
                while(!st2.empty())
                {
                    cur = st2.top();
                    v.push_back(cur->val);
                    if(cur->right) st1.push(cur->right);
                    if(cur->left) st1.push(cur->left);
                    st2.pop();
                }
                result.push_back(v);
            }
        }
    }
};
  • 队列实现,也是遍历当前队列的所有节点,同时把下一层的结点保存在另外一个队列中。如果当前层是偶数,从左往右,尾部保存结点值;奇数,从右往左,头部保存结点值。
/**
 * struct TreeNode {
 *	int val;
 *	struct TreeNode *left;
 *	struct TreeNode *right;
 *	TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 * };
 */
#include <iterator>
#include <ratio>
#include <stack>
class Solution {
public:
    vector<vector<int> > result;
    vector<vector<int> > Print(TreeNode* pRoot) {
        result.clear();
        if(pRoot == nullptr) return result;
        queuedone(pRoot);
        return result;
    }
    void queuedone(TreeNode* node)
    {
        queue<TreeNode*> que;
        vector<int> v;
        TreeNode* cur;
        if(node != nullptr) que.push(node);
        int size = 0, depth = 0;
        while (!que.empty()) 
        {
            size = que.size();
            v.clear();
            for(int i=0; i<size; i++)
            {
                cur = que.front();
                que.pop();
                if(cur == nullptr) continue;//空元素跳过
                que.push(cur->left);
                que.push(cur->right);
                if(depth % 2 == 0) v.push_back(cur->val);
                else v.insert(v.begin(), cur->val);
            }
            depth++;
            if(!v.empty()) result.push_back(v);
        }
    }
};

BM28 二叉树的最大深度

描述:求给定二叉树的最大深度,深度是指树的根节点到任一叶子节点路径上节点的数量。最大深度是所有叶子节点的深度的最大值。(注:叶子节点是指没有子节点的节点。)
数据范围:0 ≤ n ≤ 100000,树上每个节点的val满足 ∣val∣≤100
要求: 空间复杂度 O(1),时间复杂度 O(n)

  • 补充:
    使用前序求的就是深度,使用后序求的是高度。
    二叉树节点的深度:指从根节点到该节点的最长简单路径边的条数或者节点数(取决于深度从0开始还是从1开始)
    二叉树节点的高度:指从该节点到叶子节点的最长简单路径边的条数或者节点数(取决于高度从0开始还是从1开始)
    而根节点的高度就是二叉树的最大深度,所以本题中我们通过后序求的根节点高度来求的二叉树最大深度。

  • 递归法
    先求它的左子树的深度,再求右子树的深度,最后取左右深度最大的数值 再+1 (加1是因为算上当前中间节点)就是目前节点为根节点的树的深度。

/**
 * struct TreeNode {
 *	int val;
 *	struct TreeNode *left;
 *	struct TreeNode *right;
 *	TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 * };
 */
class Solution {
public:
    int maxDepth(TreeNode* root) {
        int res = 0;
        if(root == nullptr) return res;
        res = dfs(root);
        return res;
    }
    int dfs(TreeNode* root)
    {
        if(root == nullptr) return 0;
        int leftdepth = dfs(root->left);
        int rightdepth = dfs(root->right);
        int res = max(leftdepth, rightdepth) + 1;
        return res;
    }
};
  • 迭代法,队列,层序遍历
/**
 * struct TreeNode {
 *	int val;
 *	struct TreeNode *left;
 *	struct TreeNode *right;
 *	TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 * };
 */
class Solution {
public:
    int maxDepth(TreeNode* root) {
        int res = 0;
        if(root == nullptr) return res;
        //res = dfs(root);
        res = bfs(root);
        return res;
    }
    int bfs(TreeNode* root)
    {
        if(root == nullptr) return 0;
        queue<TreeNode*> que;
        que.push(root);
        int dep = 0, size = 0;
        TreeNode* temp;
        while(!que.empty())
        {
            size = que.size();
            dep++;
            for(int i=0; i<size; i++)
            {
                temp = que.front();
                que.pop();
                if(temp->left) que.push(temp->left);
                if(temp->right) que.push(temp->right);
            }
        }
        return dep;
    }
    int dfs(TreeNode* root)
    {
        if(root == nullptr) return 0;
        int leftdepth = dfs(root->left);
        int rightdepth = dfs(root->right);
        int res = max(leftdepth, rightdepth) + 1;
        return res;
    }
};

BM29 二叉树中和为某一值的路径(一)

在这里插入图片描述

  • 减法,递归
/**
 * struct TreeNode {
 *	int val;
 *	struct TreeNode *left;
 *	struct TreeNode *right;
 *	TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 * };
 */
class Solution {
public:
    bool hasPathSum(TreeNode* root, int sum) {
        if(root == nullptr) return false;
        return dfs(root, sum - root->val);
    }
    bool dfs(TreeNode* cur, int target)
    {
        //遍历到叶子节点 且为0 用减法
        //当前节点为叶子节点并且目标路径存在时
        if(cur->left == nullptr && cur->right == nullptr && target == 0) return true;
        //当前节点为叶子节点并且目标路径 不存在时
        if(cur->left == nullptr && cur->right == nullptr) return false;
        // 对左右分支进行 dfs
        if(cur->left)
        {
            target -= cur->left->val;
            if(dfs(cur->left, target)) return true;
            target += cur->left->val;
        }
        if(cur->right)
        {
            target -= cur->right->val;
            if(dfs(cur->right, target)) return true;
            target += cur->right->val;
        }
        return false;
    }
};

加法,递归

/**
 * struct TreeNode {
 *	int val;
 *	struct TreeNode *left;
 *	struct TreeNode *right;
 *	TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 * };
 */
class Solution {
public:
    bool hasPathSum(TreeNode* root, int sum) {
        if(root == nullptr) return false;
        int res = 0;
        return dfs_add(root, sum, res);
    }
    bool dfs_add(TreeNode* cur, int sum, int res)
    {
        if(cur == nullptr) return false;
        res += cur->val;
        if(!cur->left && !cur->right && res == sum) return true;
        return dfs_add(cur->left, sum, res) || dfs_add(cur->right, sum, res);        
    }
};

BM30 二叉搜索树与双向链表

描述:输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。
在这里插入图片描述
递归法,看解答的,变成双向链表,cur左指针指向上一个结点pre,pre的右指针指向cur:

  1. 二叉搜索树的最左叶子节点
  2. 中序遍历,左中右
/*
struct TreeNode {
	int val;
	struct TreeNode *left;
	struct TreeNode *right;
	TreeNode(int x) :
			val(x), left(NULL), right(NULL) {
	}
};*/
class Solution {
public:
	TreeNode* pre;
    TreeNode* Convert(TreeNode* pRootOfTree) {
        if(pRootOfTree == nullptr) return nullptr;
		TreeNode* cur = pRootOfTree;
		while(cur->left) cur = cur->left;
		inorder(pRootOfTree);
		return cur;
    }
	void inorder(TreeNode* root)
	{
		if(root == nullptr) return;
		inorder(root->left);//左
		//中 修改指向
		root->left = pre;
		if(pre)
			pre->right = root;
		pre = root;//更新pre 指向当前结点,作为下一个结点的前继
		inorder(root->right);
	}
};

用栈,迭代

/*
struct TreeNode {
	int val;
	struct TreeNode *left;
	struct TreeNode *right;
	TreeNode(int x) :
			val(x), left(NULL), right(NULL) {
	}
};*/
class Solution {
public:
	TreeNode* pre = nullptr;
	TreeNode* head = nullptr;
	stack<TreeNode*> st;
    TreeNode* Convert(TreeNode* pRootOfTree) {
        if(pRootOfTree == nullptr) return nullptr;
		stackdone(pRootOfTree);
		return head;
    }
	void stackdone(TreeNode* root)
	{
		while(!st.empty() || root != nullptr)
		{
			//找到表头
			while(root != nullptr)
			{
				st.push(root);
				root = root->left;
			}
			if(!st.empty())
			{
				//取出栈的结点
				root = st.top();
				st.pop();
				//第一次出栈的是表头
				if(pre == nullptr)
					head = root;
				else //建立双向连接
				{
					pre->right = root;
					root->left = pre;	
				}
				pre = root;//更新结点
				root = root->right;//连接链表
			}
		}
	}
};

最后两题,要再写写。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/951297.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

无涯教程-Android - Frame Layout函数

Frame Layout 旨在遮挡屏幕上的某个区域以显示单个项目&#xff0c;通常&#xff0c;应使用FrameLayout来保存单个子视图&#xff0c;因为在子视图彼此不重叠的情况下&#xff0c;难以以可扩展到不同屏幕尺寸的方式组织子视图。 不过&#xff0c;您可以使用android:layout_grav…

Unity——资产包(Asset Bundles)

对很多单机游戏来说&#xff0c;游戏的所有资源往往是与游戏本体一同发布的&#xff0c;资源部西药独立出来。但对于大型商业项目来说&#xff0c;游戏产品还需要再发布之后进行维护和更新&#xff0c;这就引出了Unity资产包的概念 一、资产包&#xff08;Asset Bundles&#x…

推荐几款常用测试数据自动生成工具(适用自动化测试、性能测试)

一、前言 在软件测试中&#xff0c;测试数据是测试用例的基础&#xff0c;对测试结果的准确性和全面性有着至关重要的影响。因此&#xff0c;在进行软件测试时&#xff0c;需要生成测试数据以满足测试场景和要求。本文将介绍如何利用测试数据生成工具来快速生成大量的测试数据…

【Windows打开OpenSSH服务端支持】

文章目录 概要整体架构流程技术细节1.安装OpenSSH服务端2.设置自启动3.启动服务4.资源监视器 修改配置防火墙小结 概要 项目需要装了一个Windows Server 2022&#xff0c;由于不能亲自到场调试&#xff0c;我就打开了OpenSSH服务支持&#xff0c;给有需要的小伙伴参考下。 整…

飞天使-python的分支结构,循环,函数

文章目录 分支结构单分支双分支多分支内联if条件语句案例&#xff0c;门票价格 循环for,in 循环for in 次数控制while 循环while遍历跳出循环break跳出循环continue 函数函数概念内置函数自定义函数函数进阶作用域 参考视频 分支结构 单分支 对事情判断&#xff0c;然后做出选…

08-Vue基础之组件

个人名片&#xff1a; &#x1f60a;作者简介&#xff1a;一名大二在校生 &#x1f921; 个人主页&#xff1a;坠入暮云间x &#x1f43c;座右铭&#xff1a;懒惰受到的惩罚不仅仅是自己的失败&#xff0c;还有别人的成功。 &#x1f385;**学习目标: 坚持每一次的学习打卡 文章…

搬家快递服务小程序的便利性

在当今快节奏的生活中&#xff0c;搬家可能是很多人都需要面对的问题。无论是新房子还是新办公室&#xff0c;都需要高效、便捷的搬家服务。本文将介绍如何使用第三方小程序制作平台&#xff0c;如乔拓云平台&#xff0c;开发一款高效便捷的搬家服务小程序。 1. 注册登录第三方…

Muscles|Tissue —— 介绍

BETA —— 此功能仍然在开发测试中&#xff0c;相关文档很少或没有&#xff0c;使用时需注意&#xff1b; 可使用Vellum-based Muscles & Tissue系统&#xff0c;模拟角色的肌肉、组织、及皮肤&#xff1b;可轻易导入模型和动画&#xff0c;并快速配置解算模拟&#xff1b;…

LeetCode第26~30题解

CONTENTS LeetCode 26. 删除有序数组中的重复项&#xff08;简单&#xff09;LeetCode 27. 移除元素&#xff08;简单&#xff09;LeetCode 28. 找出字符串中第一个匹配项的下标&#xff08;简单&#xff09;LeetCode 29. 两数相除&#xff08;中等&#xff09;LeetCode 30. 串…

Python基础知识学习与回顾

Python学习 Python基本语法 标识符 标识符由数字、字符串、下划线构成。 注意事项&#xff1a; 标识符不以数字开头区分大小写下划线开头的标识符具有特殊意义保留字&#xff0c;Python保留了一些关键字&#xff0c;这些关键字都是通过小写字母进行保存。 下划线开头的特…

前端常使用的一些网站

一.echarts Examples - Apache ECharts 身为一个资深的前端工程师 echarts 肯定是必不可少的呀 二. echarts社区 series-line折线图 - makeapie echarts社区图表可视化案例 这里面有各种大神 封装好的图例 拉下来直接使用即可 三. Element Element - The worlds most po…

【Interaction交互模块】LinearJointDrive线性关节驱动

文章目录 一、预设体位置二、案例&#xff1a;做一个“能拉动的抽屉”三、原理四、交互方式1、碰触2、抓取 一、预设体位置 交互模块——可控制物体——物理关节——线性关节驱动 二、案例&#xff1a;做一个“能拉动的抽屉” 建一个柜子外框&#xff0c;然后拓展“线性关节…

el-tree-select 树形选择的使用

案例&#xff1a; 代码&#xff1a; /**v-model:绑定的字段 */ <el-form-itemlabel"父级名称&#xff1a;"prop"ParentID"><el-tree-selectfilterablecheck-strictlyv-model"Form.ParentID":data"optionProviderType":rend…

漱玉平民大药房:多元化药店变革的前夜

作者 | 王聪彬 编辑 | 舞春秋 来源 | 至顶网 本文介绍了漱玉平民大药房在药品零售领域的数字化转型和发展历程。通过技术创新&#xff0c; 漱玉平民 建设了覆盖医药全生命周期的大健康生态圈&#xff0c;采用混合云架构和国产分布式数据库 TiDB&#xff0c;应对庞大的会员数据处…

2023年8月30日-[SWPUCTF 2021 新生赛]jicao

<?php highlight_file(index.php); include("flag.php"); $id$_POST[id]; $jsonjson_decode($_GET[json],true); if ($id"wllmNB"&&$json[x]"wllm") {echo $flag;} ?> 包含了flag.php文件&#xff0c;设定了一个POST请求的id和…

Postgresql JSON对象和数组查询

文章目录 一. Postgresql 91.1 简单查询(缺陷&#xff1a;数组必须指定下标&#xff0c;不推荐)1.1.1 模糊查询1.1.2 等值匹配1.1.3 时间搜索1.1.4 在列表1.1.5 包含 1.2 多层级JSONArray&#xff08;推荐&#xff09;1.2.1 模糊查询1.2.2 模糊查询 NOT1.2.3 等值匹配1.2.4 等值…

测试理论与方法----测试流程第三个环节:设计测试用例

测试流程第三个环节&#xff1a;设计测试用例&#xff1a;怎么测<——>测试需求的提取&#xff1a;测什么 ### 5、测试用例 描述&#xff1a;测试用例(TestCase)&#xff1a;是一份关于【具体测试步骤】的文档&#xff0c;是为了达到最佳的测试效果或高效揭露软件中潜藏的…

树形下拉框,结合ztree

1、首先引入jq 以及ztree.js 测试版本的jq是2.1.4 jauery 在线链接 https://cdn.bootcdn.net/ajax/libs/jquery/2.1.4/jquery.min.js 以下代码为ztree-select.js /*** 下拉树* 务必先引入 jQuery 和 zTree*/ (function($) {function TreeSelect() {var ts new Object();ts.…

SQL Server 2019导入txt数据

1、选择导入数据 2、选择Flat file Source 选择文件&#xff0c;如果第一行不是列名&#xff0c;就不勾选。 3、下一步 可以看看数据是否是对的 4、下一步 选择SQL server Native Client 11&#xff0c;数据库选择导入进的库 输入连接数据库的名字和要导入的数据库 下一…