LeetCode:二叉搜索树的属性、修改与构造(12道经典题目)

2023-11-14

LeetCode:二叉搜索树的属性、修改与构造(12道经典题目)




本文带来与二叉搜索树的属性、修改与构造有关的经典题目,主要实现是C++。




首先明确一下二叉搜索树的概念:

二叉搜索树是一个有序树,满足如下三个条件:

  • 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值;
  • 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;
  • 它的左、右子树也分别为二叉搜索树

特别注意的是,二叉搜索树的中序遍历是一个升序数组!!!




700. 二叉搜索树中的搜索

给定二叉搜索树(BST)的根节点 root 和一个整数值 val。你需要在 BST 中找到节点值等于 val 的节点。 返回以该节点为根的子树。 如果节点不存在,则返回 null 。

class Solution {
    public:
    TreeNode* searchBST(TreeNode* root, int val) {
        if (root == nullptr || root->val == val) return root;
        if (root->val > val) return searchBST(root->left, val);
        if (root->val < val) return searchBST(root->right, val);
        return nullptr;
    }
};

因为二叉搜索树的特殊性,也就是节点的有序性,可以不使用辅助栈或者队列就可以写出迭代法。而对于二叉搜索树,不需要回溯的过程,因为节点的有序性就帮我们确定了搜索的方向。

class Solution {
public:
	TreeNode* searchBST(TreeNode* root, int val) {
		while (root != nullptr) {
			if (root->val == val) return root;
			else if (root->val < val) root = root->right;
			else root = root->left;
		}
		return nullptr;
	}
};

98. 验证二叉搜索树

给你一个二叉树的根节点 root ,判断其是否是一个有效的二叉搜索树。有效 二叉搜索树定义如下:

  • 节点的左子树只包含 小于 当前节点的数。
  • 节点的右子树只包含 大于 当前节点的数。
  • 所有左子树和右子树自身必须也是二叉搜索树。

中序遍历下,输出的二叉搜索树节点的数值是有序序列

class Solution {
public:
	bool isValidBST(TreeNode* root) {
		vec.clear();
		traversal(root);
		for (int i = 1; i < vec.size(); i++) {
			if (vec[i] <= vec[i - 1]) return false; 
		}
		return true;
	}

	void traversal(TreeNode* cur) {
		if (cur == nullptr) return;
		traversal(cur->left);
		vec.push_back(cur->val);
		traversal(cur->right);
	}

	vector<int> vec;
};

二叉搜索树里不能有相同元素

class Solution {
public:
	bool isValidBST(TreeNode* root) {
		if (root == nullptr) return true;
		bool left = isValidBST(root->left);
		if (root->val > maxValue) maxValue = root->val;
		else return false;
		bool right = isValidBST(root->right);
		return left && right;
	}

	long long maxValue = LONG_MIN;
};

以上代码是因为后台数据有int最小值测试用例,所以都把maxVal改成了longlong最小值。如果测试数据中有 longlong的最小值,怎么办?建议避免初始化最小值,如下方法取到最左面节点的数值来比较

class Solution {
public:
	bool isValidBST(TreeNode* root) {
		if (root == nullptr) return true;
		bool left = isValidBST(root->left);
		if (pre != nullptr && pre->val >= root->val) return false;
		pre = root;
		bool right = isValidBST(root->right);
		return left && right;
	}

	TreeNode* pre;
};

迭代法求解:(只用稍微更改中序遍历)

class Solution {
public:
	bool isValidBST(TreeNode* root) {
		stack<TreeNode*> st;
		TreeNode* cur = root;
		TreeNode* pre = nullptr;
		while (cur != nullptr || !st.empty()) {
			if (cur != nullptr) {
				st.push(cur);
				cur = cur->left;
			}
			else {
				cur = st.top(); st.pop();
				if (pre != nullptr && pre->val >= cur->val) return false;
				pre = cur;
				cur = cur->right;
			}
		}
		return true;
	}
};

530. 二叉搜索树的最小绝对差

给你一个二叉搜索树的根节点 root ,返回 树中任意两不同节点值之间的最小差值 。差值是一个正数,其数值等于两值之差的绝对值。

最简单的方法就是把二叉搜索树编程一个列表,这样求最小差值就很简单了。

class Solution {
public:
	int getMinimumDifference(TreeNode* root) {
		vec.clear();
		traversal(root);
		int maxDiff = INT_MAX;
		for (int i = 1; i < vec.size(); i++) {
			maxDiff = min(maxDiff, vec[i] - vec[i - 1]);
		}
		return maxDiff;
	}

	void traversal(TreeNode* cur) {
		if (cur == nullptr) return;
		traversal(cur->left);
		vec.push_back(cur->val);
		traversal(cur->right);
		return;
	}
	vector<int> vec;
};

记录前一个节点,在遍历过程中直接计算:

class Solution {
public:
	int getMinimumDifference(TreeNode* root) {
		traversal(root);
		return result;
	}

	void traversal(TreeNode* root) {
		if (root == nullptr) return;
		if (root->left) getMinimumDifference(root->left);
		if (pre != nullptr) {
			result = min(result, root->val - pre->val);
		}
		pre = root;
		if (root->right) getMinimumDifference(root->right);
	}

private:
	int result = INT_MAX;
	TreeNode* pre;
};

501. 二叉搜索树中的众数

给你一个含重复值的二叉搜索树(BST)的根节点 root ,找出并返回 BST 中的所有 众数(即出现频率最高的元素)。如果树中有不止一个众数,可以按 任意顺序 返回。假定 BST 满足如下定义:

  • 结点左子树中所含节点的值 小于等于 当前节点的值
  • 结点右子树中所含节点的值 大于等于 当前节点的值
  • 左子树和右子树都是二叉搜索树

如果不是二叉搜索树:

class Solution {
    public:
    vector<int> findMode(TreeNode* root) {
        map.clear();
        traversal(root);
        vector<pair<int, int>> vec(map.begin(), map.end());
        sort(vec.begin(), vec.end(), cmp);
        vector<int> result;
        result.push_back(vec[0].first);
        for (int i = 1; i < vec.size(); i++) {
            if (vec[0].second == vec[i].second) result.push_back(vec[i].first);
            else break;
        }
        return result;
    }
    
    bool static cmp(pair<int, int>& a, pair<int, int>& b) {
        return a.second > b.second; // 按照频率从大到小排序
    }
    
    void traversal(TreeNode* cur) {
        if (cur == nullptr) return;
        traversal(cur->left);
        map[cur->val]++;
        traversal(cur->right);
        return;
    }
    
    map<int, int> map;
};

C++中如果使用std::map或者std::multimap可以对key排序,但不能对value排序。所以要把map转化数组即vector,再进行排序,当然vector里面放的也是pair<int, int>类型的数据,第一个int为元素,第二个int为出现频率。

是二叉搜索树:

既然是搜索树,它中序遍历就是有序的!

从头遍历,比较相邻两个节点的元素,然后就把出现频率最高的元素输出。定义指针pre指向前一个节点,这样就可以比较相邻节点了。

class Solution {
public:
	vector<int> findMode(TreeNode* root) {
		count = 0;
		maxCount = 0;
		TreeNode* pre = nullptr;
		result.clear();
		traversal(root);
		return result;
	}

	void traversal(TreeNode* cur) {
		if (cur == nullptr) return;

		traversal(cur->left);

		if (pre == nullptr) count = 1; // 第一个节点
		else if (pre->val == cur->val) count++;
		else count = 1; // 与前一个节点数值不同

		pre = cur;  // 更新上一个节点

		if (count == maxCount) result.push_back(cur->val);
		else if (count > maxCount) {
			maxCount = count;
			result.clear();
			result.push_back(cur->val);
		}

		traversal(cur->right);
		return;
	}

private:
	TreeNode* pre;
	int maxCount; // 最大频率
	int count; // 统计频率
	vector<int> result;
};
class Solution {
public:
	vector<int> findMode(TreeNode* root) {
		stack<TreeNode*> st;
		TreeNode* pre = nullptr;
		TreeNode* cur = root;
		int maxCount = 0;
		int count = 0;
		vector<int> vec;
		while (cur != nullptr || !st.empty()) {
			if (cur != nullptr) {
				st.push(cur);
				cur = cur->left;
			}
			else {
				cur = st.top();
				st.pop();

				if (pre == nullptr) count = 1;
				else if (pre->val == cur->val) count++;
				else count = 1;
				pre = cur;

				if (maxCount == count) {
					vec.push_back(cur->val);
				}
				if (maxCount < count) {
					maxCount = count;
					vec.clear();
					vec.push_back(cur->val);
				}
				cur = cur->right;
			}
		}
		return vec;
	}
};

236. 二叉树的最近公共祖先

给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。

百度百科中最近公共祖先的定义为:“对于有根树 T 的两个节点 p、q,最近公共祖先表示为一个节点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”

利用回溯自底向上查找!后序遍历就是天然的回溯过程,最先处理的一定是叶子节点。
**如果找到一个节点,发现左子树出现结点p,右子树出现节点q,或者 左子树出现结点q,右子树出现节点p,那么该节点就是节点p和q的最近公共祖先。**使用后序遍历,回溯的过程,就是从低向上遍历节点,一旦发现如何这个条件的节点,就是最近公共节点了。

如果递归函数有返回值,如何区分要搜索一条边,还是搜索整个树呢?
搜索一条边的写法:

if (递归函数(root->left)) return ;
if (递归函数(root->right)) return ;

搜索整个树写法:

left = 递归函数(root->left); 
right = 递归函数(root->right); 
left与right的逻辑处理;

在递归函数有返回值的情况下:如果要搜索一条边,递归函数返回值不为空的时候,立刻返回,如果搜索整个树,直接用一个变量left、right接住返回值,这个left、right后序还有逻辑处理的需要,也就是后序遍历中处理中间节点的逻辑(也是回溯)

class Solution {
public:
	TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
		if (root == p || root == q || root == nullptr) return root;
		TreeNode* left = lowestCommonAncestor(root->left, p, q);
		TreeNode* right = lowestCommonAncestor(root->right, p, q);
		if (left != nullptr && right != nullptr) return root;

		if (left == nullptr && right != nullptr) return right;
		else if (left != nullptr && right == nullptr) return left;
		else return nullptr;
	}
};

235. 二叉搜索树的最近公共祖先

给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。


在有序树里,如果判断一个节点的左子树里有p,右子树里有q呢?
其实只要从上到下遍历的时候,cur节点是数值在[p, q]区间中则说明该节点cur就是最近公共祖先了。

class Solution {
public:
	TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
		return traversal(root, p, q);
	}

	TreeNode* traversal(TreeNode* cur, TreeNode* p, TreeNode* q) {
		if (cur == nullptr) return cur;
		if (cur->val > p->val && cur->val > q->val) {
			TreeNode* left = traversal(cur->left, p, q);
			if (left != nullptr) return left;
		}
		if (cur->val < p->val && cur->val < q->val) {
			TreeNode* right = traversal(cur->right, p, q);
			if (right != nullptr) return right;
		}
		return cur;
	}
};
class Solution {
public:
	TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
		while (root) {
			if (root->val > p->val && root->val > q->val) {
				root = root->left;
			}
			else if (root->val < p->val && root->val < q->val) {
				root = root->right;
			}
			else return root;
		}
		return nullptr;
	}
};

701. 二叉搜索树中的插入操作

给定二叉搜索树(BST)的根节点 root 和要插入树中的值 value ,将值插入二叉搜索树。 返回插入后二叉搜索树的根节点。 输入数据 保证 ,新值和原始二叉搜索树中的任意节点值都不同。

class Solution {
    public:
    TreeNode* insertIntoBST(TreeNode* root, int val) {
        if (root == nullptr) {
            TreeNode* node = new TreeNode(val);
            return node;
        }
        if (root->val > val) root->left = insertIntoBST(root->left, val);
        if (root->val < val) root->right = insertIntoBST(root->right, val);
        
        return root;
    }
};

递归函数不用返回值也可以,找到插入的节点位置,直接让其父节点指向插入节点,结束递归。没有返回值,需要记录上一个节点(parent),遇到空节点了,就让parent左孩子或者右孩子指向新插入的节点。然后结束递归。

class Solution {
public:
	TreeNode* insertIntoBST(TreeNode* root, int val) {
		parent = new TreeNode(0);
		if (root == nullptr) {
			root = new TreeNode(val);
		}
		traversal(root, val);
		return root;
	}

	void traversal(TreeNode* cur, int val) {
		if (cur == nullptr) {
			TreeNode* node = new TreeNode(val);
			if (val > parent->val) parent->right = node;
			else parent->left = node;
			return;
		}
		parent = cur;
		if (cur->val < val) traversal(cur->right, val);
		if (cur->val > val) traversal(cur->left, val);
		return;
	}

	TreeNode* parent;
};
class Solution {
public:
	TreeNode* insertIntoBST(TreeNode* root, int val) {
		if (root == nullptr) {
			TreeNode* node = new TreeNode(val);
			return node;
		}
		TreeNode* cur = root;
		TreeNode* parent = nullptr;
		while (cur != nullptr) {
			parent = cur;
			if (cur->val > val) cur = cur->left;
			else cur = cur->right;
		}

		TreeNode* node = new TreeNode(val);
		if (val < parent->val) parent->left = node;
		else parent->right = node;

		return root;
	}
};

450. 删除二叉搜索树中的节点

给定一个二叉搜索树的根节点 root 和一个值 key,删除二叉搜索树中的 key 对应的节点,并保证二叉搜索树的性质不变。返回二叉搜索树(有可能被更新)的根节点的引用。一般来说,删除节点可分为两个步骤:

  • 首先找到需要删除的节点;
  • 如果找到了,删除它。

有以下五种情况:

  • 第一种情况:没找到删除的节点,遍历到空节点直接返回了
  • 找到删除的节点
    • 第二种情况:左右孩子都为空(叶子节点),直接删除节点, 返回NULL为根节点
    • 第三种情况:删除节点的左孩子为空,右孩子不为空,删除节点,右孩子补位,返回右孩子为根节点
    • 第四种情况:删除节点的右孩子为空,左孩子不为空,删除节点,左孩子补位,返回左孩子为根节点
    • 第五种情况:左右孩子节点都不为空,则将删除节点的左子树头结点(左孩子)放到删除节点的右子树的最左面节点的左孩子上,返回删除节点右孩子为新的根节点。
class Solution {
public:
	TreeNode* deleteNode(TreeNode* root, int key) {
		if (root == nullptr) return root;
		if (root->val == key) {
			if (root->left == nullptr && root->right == nullptr) {
				delete root;
				return nullptr;
			}
			else if (root->left == nullptr) {
				TreeNode* retNode = root->right;
				delete root;
				return retNode;
			}
			else if (root->right == nullptr) {
				TreeNode* retNode = root->left;
				delete root;
				return retNode;
			}
			else {
				TreeNode* cur = root->right;
				while (cur->left != nullptr) {
					cur = cur->left;
				}
				cur->left = root->left;
				TreeNode* tmp = root;
				root = root->right;
				delete tmp;
				return root;
			}
		}
		if (root->val < key) root->right = deleteNode(root->right, key);
		if (root->val > key) root->left = deleteNode(root->left, key);
		return root;
	}
};

669. 修剪二叉搜索树

给你二叉搜索树的根节点 root ,同时给定最小边界low 和最大边界 high。通过修剪二叉搜索树,使得所有节点的值在[low, high]中。修剪树 不应该 改变保留在树中的元素的相对结构 (即,如果没有被移除,原有的父代子代关系都应当保留)。 可以证明,存在 唯一的答案 。所以结果应当返回修剪好的二叉搜索树的新的根节点。注意,根节点可能会根据给定的边界发生改变。

class Solution {
public:
	TreeNode* trimBST(TreeNode* root, int low, int high) {
        // 修剪的操作并不是在终止条件上进行的,遇到空节点返回就可以了。
		if (root == nullptr) return nullptr;
        
        // 如果当前节点的元素小于low的数值,那么应该递归右子树
		if (root->val < low) {
			return trimBST(root->right, low, high);  // 寻找符合区间[low, high]的节点
		}
        // 当前节点的元素大于high的,那么应该递归左子树
		if (root->val > high) {
			return trimBST(root->left, low, high);
		}

		root->left = trimBST(root->left, low, high);  // root->left接入符合条件的左孩子
		root->right = trimBST(root->right, low, high); // root->right接入符合条件的右孩子
		return root;
	}
};

因为二叉搜索树的有序性,不需要使用栈模拟递归的过程。在剪枝的时候,可以分为三步:

  • 将root移动到[L, R] 范围内,注意是左闭右闭区间
  • 剪枝左子树
  • 剪枝右子树
class Solution {
public:
	TreeNode* trimBST(TreeNode* root, int low, int high) {
		if (root == nullptr) return nullptr;

		// 处理头结点,让root移动到[L, R] 范围内,注意是左闭右闭
		while (root != nullptr && (root->val < low || root->val > high)) {
			if (root->val < low) root = root->right;
			else root = root->left;
		}

		TreeNode* cur = root;
		// 此时root已经在[L, R] 范围内,处理左孩子元素小于L的情况
		while (cur != nullptr) {
			while (cur->left != nullptr && cur->left->val < low) {
				cur->left = cur->left->right;
			}
			cur = cur->left;
		}

		cur = root;
		// 此时root已经在[L, R] 范围内,处理右孩子大于R的情况
		while (cur != nullptr) {
			while (cur->right != nullptr && cur->right->val > high) {
				cur->right = cur->right->left;
			}
			cur = cur->right;
		}

		return root;
	}
};

108. 将有序数组转换为二叉搜索树

给你一个整数数组 nums ,其中元素已经按 升序 排列,请你将其转换为一棵 高度平衡 二叉搜索树。

高度平衡 二叉树是一棵满足「每个节点的左右两个子树的高度差的绝对值不超过 1 」的二叉树。

这里不用强调平衡二叉搜索树,数组构造二叉树,构成平衡树是自然而然的事情,因为默认都是从数组中间位置取值作为节点元素,一般不会随机取。

本质就是寻找分割点,分割点作为当前节点,然后递归左区间和右区间。有序数组构造二叉搜索树,寻找分割点比较容易,分割点就是数组中间位置的节点。如果数组长度为偶数,中间节点有两个,取哪一个都可以,只不过构成了不同的平衡二叉搜索树。

class Solution {
public:
	TreeNode* sortedArrayToBST(vector<int>& nums) {
		return traversal(nums, 0, nums.size() - 1);
	}

	// 左闭右闭
	TreeNode* traversal(vector<int>& nums, int left, int right) {
		if (left > right) return nullptr;
		int mid = left + (right - left) / 2;
		TreeNode* root = new TreeNode(nums[mid]);
		root->left = traversal(nums, left, mid - 1);
		root->right = traversal(nums, mid + 1, right);
		return root;
	}
};

迭代法可以通过三个队列来模拟,一个队列放遍历的节点,一个队列放左区间下标,一个队列放右区间下标。

class Solution {
public:
	TreeNode* sortedArrayToBST(vector<int>& nums) {
		if (nums.size() == 0) return nullptr;

		TreeNode* root = new TreeNode(0);  // 初始根节点

		queue<TreeNode*> nodeQue; // 放遍历的节点
		queue<int> leftQue;  // 保存左区间下标
		queue<int> rightQue;  // 保存右区间下标
		nodeQue.push(root);
		leftQue.push(0);
		rightQue.push(nums.size() - 1);

		while (!nodeQue.empty()) {
			TreeNode* curNode = nodeQue.front(); nodeQue.pop();
			int left = leftQue.front(); leftQue.pop();
			int right = rightQue.front(); rightQue.pop();

			int mid = left + (right - left) / 2;
			curNode->val = nums[mid];

			if (left <= mid - 1) { // 处理左区间
				curNode->left = new TreeNode(0);
				nodeQue.push(curNode->left);
				leftQue.push(left);
				rightQue.push(mid - 1);
			}

			if (right > mid) { // 处理右区间
				curNode->right = new TreeNode(0);
				nodeQue.push(curNode->right);
				leftQue.push(mid + 1);
				rightQue.push(right);
			}
		}
		return root;
	}
};

538. 把二叉搜索树转换为累加树

给出二叉搜索树的根节点,该树的节点值各不相同,请你将其转换为累加树(Greater Sum Tree),使每个节点 node 的新值等于原树中大于或等于 node.val 的值之和。

PS. 这道题和下面这道题一模一样,读不懂的可以看下面这道题。

1038. 从二叉搜索树到更大和树

给定一个二叉搜索树 root (BST),请将它的每个节点的值替换成树中大于或者等于该节点值的所有节点值之和。


从树中可以看出累加的顺序是右中左,所以我们需要反中序遍历这个二叉树,然后顺序累加就可以了。

class Solution {
public:
	int pre;  // 记录前一个节点的数值

	void traversal(TreeNode* root) {
		if (root == nullptr) return;
		traversal(root->right);  // 右
		root->val += pre;  // 中
		pre = root->val;
		traversal(root->left);  // 左
		return;
	}

	TreeNode* convertBST(TreeNode* root) {
		pre = 0;
		traversal(root);
		return root;
	}
};
class Solution {
public:
	TreeNode* convertBST(TreeNode* root) {
		if (root == nullptr) return nullptr;
		stack<TreeNode*> st;
		TreeNode* cur = root;
		int pre = 0;
		while (cur != nullptr || !st.empty()) {
			if (cur != nullptr) {
				st.push(cur);
				cur = cur->right;  // 右
			}
			else {
				cur = st.top();
				st.pop();
				cur->val += pre;  // 中
				pre = cur->val;

				cur = cur->left;  // 左
			}
		}
		return root;
	}
};



以上题解大多来自【代码随想录】(完整版看这个!!),在此基础上做了一定总结,并附带一些自己的理解。

后续题目,随缘更新,有错误请指出!

END

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

LeetCode:二叉搜索树的属性、修改与构造(12道经典题目) 的相关文章

  • 检查两个数是否是彼此的排列?

    给定两个数字 a b 使得 1 例如 123 是 312 的有效排列 我也不想对数字中的数字进行排序 如果您指的是数字的字符 例如 1927 和 9721 则 至少 有几种方法 如果允许排序 一种方法是简单地sprintf将它们放入两个缓冲
  • 如何使 Windows 窗体的关闭按钮不关闭窗体但使其不可见?

    该表单有一个 NotifyIcon 对象 当用户单击 关闭 按钮时 我希望表单不关闭而是变得不可见 然后 如果用户想再次查看该表单 可以双击系统托盘中的图标 如果用户想关闭表单 可以右键单击该图标并选择 关闭 有人可以告诉我如何使关闭按钮不
  • 访问私人成员[关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 通过将类的私有成员转换为 void 指针 然后转换为结构来访问类的私有成员是否合适 我认为我无权修改包含我需要访问的数据成员的类 如果不道德 我
  • ASP.NET Core Serilog 未将属性推送到其自定义列

    我有这个设置appsettings json对于我的 Serilog 安装 Serilog MinimumLevel Information Enrich LogUserName Override Microsoft Critical Wr
  • Qt-Qlist 检查包含自定义类

    有没有办法覆盖加载自定义类的 Qt QList 的比较机制 即在 java 中你只需要重写一个比较方法 我有一个带有我的自定义类模型的 QList QList
  • 将数组向左或向右旋转一定数量的位置,复杂度为 o(n)

    我想编写一个程序 根据用户的输入 正 gt 负 include
  • linux perf:如何解释和查找热点

    我尝试了linux perf https perf wiki kernel org index php Main Page今天很实用 但在解释其结果时遇到了困难 我习惯了 valgrind 的 callgrind 这当然是与基于采样的 pe
  • 如何在列表框项目之间画一条线

    我希望能够用水平线分隔列表框中的每个项目 这只是我用于绘制项目的一些代码 private void symptomsList DrawItem object sender System Windows Forms DrawItemEvent
  • 实时服务器上的 woff 字体 MIME 类型错误

    我有一个 asp net MVC 4 网站 我在其中使用 woff 字体 在 VS IIS 上运行时一切正常 然而 当我将 pate 上传到 1and1 托管 实时服务器 时 我得到以下信息 网络错误 404 未找到 http www co
  • 指针问题(仅在发布版本中)

    不确定如何描述这一点 但我在这里 由于某种原因 当尝试创建我的游戏的发布版本进行测试时 它的敌人创建方面不起作用 Enemies e level1 3 e level1 0 Enemies sdlLib 500 2 3 128 250 32
  • 在 Visual Studio 2008 上设置预调试事件

    我想在 Visual Studio 中开始调试程序之前运行一个任务 我每次调试程序时都需要运行此任务 因此构建后事件还不够好 我查看了设置的 调试 选项卡 但没有这样的选项 有什么办法可以做到这一点吗 你唯一可以尝试的 IMO 就是尝试Co
  • vector 超出范围后不清除内存

    我遇到了以下问题 我不确定我是否错了或者它是一个非常奇怪的错误 我填充了一个巨大的字符串数组 并希望在某个点将其清除 这是一个最小的例子 include
  • 从路径中获取文件夹名称

    我有一些路c server folderName1 another name something another folder 我如何从那里提取最后一个文件夹名称 我尝试了几件事 但没有成功 我只是不想寻找最后的 然后就去休息了 Thank
  • 如何衡量两个字符串之间的相似度? [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 给定两个字符串text1 and text2 public SOMEUSABLERETURNTYPE Compare string t
  • Qt表格小部件,删除行的按钮

    我有一个 QTableWidget 对于所有行 我将一列的 setCellWidget 设置为按钮 我想将此按钮连接到删除该行的函数 我尝试了这段代码 它不起作用 因为如果我只是单击按钮 我不会将当前行设置为按钮的行 ui gt table
  • Discord.net 无法在 Linux 上运行

    我正在尝试让在 Linux VPS 上运行的 Discord net 中编码的不和谐机器人 我通过单声道运行 但我不断收到此错误 Unhandled Exception System Exception Connection lost at
  • 实体框架 4 DB 优先依赖注入?

    我更喜欢创建自己的数据库 设置索引 唯一约束等 使用 edmx 实体框架设计器 从数据库生成域模型是轻而易举的事 现在我有兴趣使用依赖注入来设置一些存储库 我查看了 StackOverflow 上的一些文章和帖子 似乎重点关注代码优先方法
  • 在 Dynamics CRM 插件中访问电子邮件发件人地址

    我正在编写一个 Dynamics CRM 2011 插件 该插件挂钩到电子邮件实体的更新后事件 阶段 40 pipeline http msdn microsoft com en us library gg327941 aspx 并且在此阶
  • 为什么 C# Math.Ceiling 向下舍入?

    我今天过得很艰难 但有些事情不太对劲 在我的 C 代码中 我有这样的内容 Math Ceiling decimal this TotalRecordCount this PageSize Where int TotalRecordCount
  • 如何使用 std::string 将所有出现的一个字符替换为两个字符?

    有没有一种简单的方法来替换所有出现的 in a std string with 转义 a 中的所有斜杠std string 完成此操作的最简单方法可能是boost字符串算法库 http www boost org doc libs 1 46

随机推荐

  • 人脸识别手把手教学传送门

    http t csdn cn cVdHb
  • 2023 hdu 第10场 1004 Do you Like Interactive Problem

    Problem Description 现在有一个整数 x x x 1 x n
  • 分布式集群框架——Google文件系统GFS

    Google文件系统GFS Google文件系统 Google File System GFS 是一个大型的分布式文件系统 它为Google云计算提供海量存储 并且与Chubby MapReduce以及Bigtable等技术结合十分紧密 处
  • jenkins 配置root用户

    修改用户为root 避免权限导致的问题 vim etc sysconfig jenkins 修改目录权限 chown R root root var lib jenkins chown R root root var cache jenki
  • 数据库系列MySQL:优化配置文件

    配置流程 1 MySQL文件目录中后缀名为 ini文件的就是MySQL的默认配置文件 2 程序启动会先加载配置文件中的的配置 之后才会真正启动程序 3 更改完配置文件设置后需要重新启动服务端才可以生效 优化方案一 服务器内存 4 8GB k
  • linux释放buff/cache缓存空间

    当free m发现操作系统buff cache占用缓存过高导致可用内存过小时 这是后需要手动释放一下缓存 输入命令 echo 3 gt proc sys vm drop caches
  • Flask App 数据发送到 PostgreSQL 数据库

    对象关系映射器 如果您计划制作任何类型的现代 Web 服务 那么管理通过网站或应用程序的数据流是一项需要掌握的关键技能 使用flask 对象关系映射器 ORM 被用来让你的应用程序与关系数据库进行交互 对象关系映射器是一个框架 在我们的例子
  • [Echarts可视化] 一.入门篇之简单绘制中国地图和贵州地区

    最近发生了很多事情 去到了一个新环境学习 但是不论在哪里 我都需要不忘初心 坚持做自己喜欢的事情 在CSDN写博客 教学 爱娜 生活等等 这篇文章主要是通过Echarts可视化介绍入门知识 中国地图和贵州地区各省份的数据分析 其中贵州地图才
  • 在Windows Server 2016 Hyper-V中开启嵌套虚拟化(NestedVM)

    早期如果我们想做Hyper V功能测试 例如Hyper V Cluster或者Hyper V Replica时至少使用两台物理机器实现 作为大众屌丝没那么多钱购买机器怎么办 嵌套虚拟化 嵌套虚拟化 顾名思义 即在虚拟机中运行虚拟机 该技术最
  • 微信小程序开发--uniapp

    uniapp介绍 什么是uniapp uniapp是一个使用Vue js开发所有前端应用的框架 开发者编写一套代码 可发布到iOS Android H5 以及各种小程序 微信 支付宝 百度 头条 QQ 钉钉 淘宝 快应用等多个平台 截止20
  • 破解selenium封禁--去哪儿酒店爬虫

    使用selenium遇到封禁 selenium是我用来破解一些js渲染比较多的页面的神器 但是最近 在抓取一些网站时 遇到了让人头皮发麻的事情 selenium出问题了 在测试去哪儿酒店时 遇到了加载不出数据的问题 如下图 去哪儿会一直很努
  • linux配置nginx下载包安装的方式

    0 先卸载nginx 使用yum来卸载 yum remove nginx 查询所有nginx相关文件 逐一删除 whereis nginx rm rf 文件名或目录 1 安装编译环境 yum y install make zlib zlib
  • MQTT 连接优化指南

    博主猫头虎 带您 Go to New World 博客首页 猫头虎的博客 面试题大全专栏 文章图文并茂 生动形象 简单易学 欢迎大家来踩踩 IDEA开发秘籍专栏 学会IDEA常用操作 工作效率翻倍 100天精通Golang 基础入门篇 学会
  • 华为OD机试 - 数组去重和排序(Java)

    题目描述 给定一个乱序的数组 删除所有的重复元素 使得每个元素只出现一次 并且按照出现的次数从高到低进行排序 相同出现次数按照第一次出现顺序进行先后排序 输入描述 一个数组 输出描述 去重排序后的数组 用例 输入 1 3 3 3 2 4 4
  • redis-缓存架构-问题列表(四)

    1 缓存架构 高并发 高可用 解决方案 问题 1 如何让redis集群支撑几十万QPS高并发 99 99 高可用 TB级海量数据 企业级数据备份与恢复 redis企业级集群架构 2 如何支撑高性能以及高并发到极致 同时给缓存架构最后的安全保
  • Java如何将字符串放进字符串数组中(亲测)

    String str1 aaa String str2 bbb String str3 ccc List
  • oracle报错文件损坏,oracle 控制文件损坏处理

    一 故障模拟 控制文件损坏 发现关闭不了 强制关闭 故障恢复 发现已经执行到mont阶段 因为这个不依靠控制文件 进入整段日志 cd u01 app oracle diag rdbms orcl orcl trace 查看alert orc
  • Idea开启Run DashBoard配置

    找到 idea文件下的workspace xml 并找到RunDashboard
  • LeetCode:二叉搜索树的属性、修改与构造(12道经典题目)

    LeetCode 二叉搜索树的属性 修改与构造 12道经典题目 本文带来与二叉搜索树的属性 修改与构造有关的经典题目 主要实现是C 700 二叉搜索树中的搜索 98 验证二叉搜索树 530 二叉搜索树的最小绝对差 501 二叉搜索树中的众数