算法练习----力扣每日一题------7

原题链接

1483. 树节点的第 K 个祖先 - 力扣(LeetCode)

题目解析

        要求编写一个TreeAncestor类,需要为其写两个函数。该类是一个无规律的多叉树,多叉树的父节点一定是0号节点

 1.        TreeAncestor(int n, vector<int>& parent)

n为parent的长度,也为多叉树的节点个数,parent中存的是每个节点的父节点的编号,例如parent[3] = 1代表3号节点的父节点是1号节点

2.         int getKthAncestor(int node, int k)

node为节点序号,k是一个计数器,该函数要求返回node节点的第k辈祖先节点的序号,如果不存在返回-1

  • 1 <= k <= n <= 5 * 10^4
  • parent[0] == -1 表示编号为 0 的节点是根节点。
  • 对于所有的 0 < i < n ,0 <= parent[i] < n 总成立
  • 0 <= node < n
  • 至多调用 5 * 10^4 次getKthAncestor

解题:

两种不合题意的解法:

直接暴力求解:

超时

class TreeAncestor {
public:
    TreeAncestor(int n, vector<int>& parent) {
        tmp = {parent.begin(),parent.end()};
    }
    
    int getKthAncestor(int node, int k) {
        
        while(k--)
        {
            if(node == 0)
                return -1;
            node = tmp[node];
        }
        return node;
    }
    vector<int> tmp;
};

构造函数时间复杂度o(n)空间复杂度o(n)

get函数时间复杂度o(k)  空间复杂度o(1)

假设调用a次get:总时间复杂度o(k*a+n)空间复杂度o(n)

优化暴力

超空间

在暴力解法中每次调用get都会从node开始一直向前算,这些计算很可能在之前的遍历中都算过了。如果我们在执行循环之前把所有的情况都算出来,之后调用get时就可以直接得到。

class TreeAncestor {
public:
	TreeAncestor(int n, vector<int>& parent) {
		tmp = { parent.begin(),parent.end() };
		r.resize(tmp.size());
		for (int i = 1; i < tmp.size(); i++)
		{
			for (int j = i; j >= 0; j = tmp[j])
			{
				r[i].push_back(j);
			}
		}
	}

	int getKthAncestor(int node, int k) {
		if (k >= r[node].size())
			return -1;
		else
			return r[node][k];
	}
	vector<int> tmp;
	vector<vector<int>> r;
};

构造函数时间复杂度o(n*n)空间复杂度o(n*n)

get函数时间复杂度o(1)  空间复杂度o(1)

假设调用a次get:总时间复杂度o(n*n)空间复杂度o(n*n)

倍增记录法

既然优化暴力法会超空间限制,想办法只取一部分的数据进行记录即可。

class TreeAncestor 
{
public:
	const int num = 16;
	vector<vector<int>>a;
	TreeAncestor(int n, vector<int>& parent) 
	{
		a.resize(n, vector<int>(num, -1));
		for (int i = 0; i < n; i++)
		{
			a[i][1] = parent[i];
		}
		for (int j = 2; j < num; j++)
		{
			for (int i = 0; i < n; i++)
			{
				if (a[i][j-1] != -1)
					a[i][j] = a[a[i][j - 1]][j - 1];
			}
		}
	}

	int getKthAncestor(int node, int k) {
		int tmp = 0;
		while (k != 0)
		{
			if (node == -1)
				return -1;
			int a1 = 1,a2=0;
			while (a1 <= k)
				a1 *= 2,a2++;
			k -= a1 / 2;
			node = a[node][ a2 ];
		}
		return node;
	}
};

构造函数时间复杂度o(n*log(n))空间复杂度o(n*log(n))

get函数时间复杂度o(log(k))  空间复杂度o(1)

假设调用a次get:总时间复杂度o(n*log(n)+a*log(k))空间复杂度o(n*log(n))


感谢观看!!!!

相关推荐

  1. 算法练习----每日------7

    2024-04-07 15:22:06       43 阅读
  2. 算法练习----每日------1

    2024-04-07 15:22:06       48 阅读
  3. 算法练习----每日------2

    2024-04-07 15:22:06       29 阅读
  4. 算法练习----每日------3

    2024-04-07 15:22:06       40 阅读
  5. 算法练习----每日------5

    2024-04-07 15:22:06       38 阅读
  6. 算法练习----每日------6

    2024-04-07 15:22:06       37 阅读
  7. 算法练习----每日------4

    2024-04-07 15:22:06       43 阅读
  8. 每日 6/7

    2024-04-07 15:22:06       35 阅读
  9. 2024.1.7每日——赎金信

    2024-04-07 15:22:06       65 阅读
  10. 每日

    2024-04-07 15:22:06       38 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-04-07 15:22:06       98 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-04-07 15:22:06       106 阅读
  3. 在Django里面运行非项目文件

    2024-04-07 15:22:06       87 阅读
  4. Python语言-面向对象

    2024-04-07 15:22:06       96 阅读

热门阅读

  1. C++初级---模板初阶

    2024-04-07 15:22:06       41 阅读
  2. 多线程(36)AtomicStampedReference

    2024-04-07 15:22:06       42 阅读
  3. 上升Chrome安装Vue插件vue-devtools

    2024-04-07 15:22:06       31 阅读
  4. 基于开源软件构建存储解决方案的思考

    2024-04-07 15:22:06       37 阅读
  5. [Qt]解析moc文件

    2024-04-07 15:22:06       25 阅读