剑指offer系列题解(十)-C++版

11 篇文章 1 订阅

1.二叉树的深度

  输入一棵二叉树,求该树的深度。从根结点到叶结点依次经过的结点(含根、叶结点)形成树的一条路径,最长路径的长度为树的深度。

若一棵树有个结点,其深度为1,若只有左子树则左子树的深度加1,若只有右子树则右子树的深度加1,若既有左子树又有右子树,则是左,右子树的深度较大值加1,因此在遍历的过程中增加计数与比较,递归解决。

/*
struct TreeNode {
	int val;
	struct TreeNode *left;
	struct TreeNode *right;
	TreeNode(int x) :
			val(x), left(NULL), right(NULL) {
	}
};*/
class Solution {
public:
	int TreeDepth(TreeNode* pRoot)
	{
		if (pRoot == nullptr)
			return 0;
		
		int dleft = TreeDepth(pRoot->left);
		int dright = TreeDepth(pRoot->right);

		return (dleft > dright) ?  (dleft + 1) : (dright + 1);

	}
};
2.平衡二叉树

  输入一棵二叉树,判断该二叉树是否是平衡二叉树。只需要考虑其平衡性。

平衡的二叉树要求每个结点的左右子树的深度差不超过1,经过上题,获取左右子树深度后,进行比较即可处理。

class Solution {
public:
    bool flag = true;
    bool IsBalanced_Solution(TreeNode* pRoot) {
        getDepth(pRoot);
        return flag;
    }

    int getDepth(TreeNode* pRoot)
    {
        if(pRoot == NULL)
            return 0;
        int left = getDepth(pRoot->left);
        int right = getDepth(pRoot->right);

        if(abs(left -right) > 1)
            flag = false;

        return (left>right?left:right)+1;

    }
};

上述方法中,一个结点会重复遍历多次,造成消耗。结合二叉树的遍历,后序遍历的方式中,遍历一个结点之前就可以遍历其左右子树,在后续遍历的过程中记录深度进行处理。

class Solution {
public:
	bool IsBalanced(TreeNode* pRoot, int& depth)
	{
		if (pRoot == nullptr)
		{
			depth = 0;
			return true;
		}

		int left = 0, right = 0;
		if (IsBalanced(pRoot->left, left) && IsBalanced(pRoot->right, right))
		{
			if (abs(left - right) <= 1)
			{
				depth = (left > right ? left : right) + 1;
				return true;
			}
		}

		return false;
	}

	bool IsBalanced_Solution(TreeNode* pRoot) {
		int depth = 0;
		
		return IsBalanced(pRoot, depth);
	}
};
3.数组中只出现一次的数字

  一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。

依据相同的数字异或结果为0,通过将数组中的数字进行异或获得两个只出现一次数字的异或结果,然后通过寻找结果的二进制值中第一次出现1的位置n,通过判断整个数组中元素的二进制值第n位是否为1,将数组分为两个子数组,这两个子数组中各自包含了一个只出现一次的数字

class Solution {
public:
	bool IndexBitIs1(int num, unsigned int index)
	{
		num = num >> index;

		return (num & 1);
	}
	void FindNumsAppearOnce(vector<int> data, int* num1, int *num2) {
		if (data.size() == 0)
			return;

		int resOr = 0;
		for (int i = 0; i < data.size(); i++)
		{
			resOr ^= data[i];
		}

		unsigned int index = 0;
		while (((resOr & 1) == 0) && (index < 8 * sizeof(int)))
		{
			resOr = resOr >> 1;
			index++;
		}

		*num1 = *num2 = 0;

		for (int i = 0; i < data.size(); i++)
		{
			if (IndexBitIs1(data[i], index))
			{
				*num1 ^= data[i];
			}
			else
			{
				*num2 ^= data[i];
			}
		}

	}
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值