力扣104. 力扣108. 力扣1217

前言

俺又回来啦,考试周终于完事了,休息了两天,今天开始继续干活!
先做点简单题找找手感,过两天再加深难度。
假期就会开洛谷专题,希望大家多多捧场,多多提出意见,谢谢大家!

题目一要求:

在这里插入图片描述

整体思路

经典回溯法,因为二叉树结构肯能会分出很多的枝杈,如果从上到下统计,只能遍历到叶子节点再统一计算,也是可以的,但是并没有回溯好想。每个节点闻讯左右儿子,让其上报他们的深度,为了把他们都装进来,所以取二者最大值,因为要将该节点自己也得计算进来,所以在此基础上+1即可。循环往复逐层上报就行了。

具体代码

class Solution {
public:
	int maxDepth(TreeNode* root) {
		if (root == nullptr) {//当到了空节点返回0,千万别返回1,因为空节点不算深度。
			return 0;
		}
		return max(maxDepth(root->left), maxDepth(root->right)) + 1;
	}
};

(所有代码均已在力扣上运行无误)

经测试,该代码运行情况是(经过多次测试所得最短时间):

在这里插入图片描述

时间复杂度:
在这里插入图片描述

题目二要求:

在这里插入图片描述
在这里插入图片描述

整体思路 :经典回溯

1、nums数组是一个严格递增的一个数组,说明是二叉搜索树的中序遍历,每个节点都是一个根,他的左面都小于它,右面都大于它,根据此我们能确定很多种二叉搜索树。
2、但是再看题,要求高度平衡,这样就会砍下去很多无效树,所以我们用贪心的思想,每一次选择中间的节点作为根节点,左面的序列是左子树,右面的序列是右子树,当序列的个数是奇数时候,左右个数相等,反之最多差一,关于此种选择方法是否一定构造出高度平衡以及贪心算法正确性证明,详见力扣官方题解
3、最后就是选择中间结点的方法了,根据题意,中间节点不受限制,所以可以靠左,也可以靠右,也可以随机。

具体代码

class Solution {
public:
	TreeNode* sortedArrayToBST(vector<int>& nums) {
		if (nums.size() == 0) {
			return nullptr;//初始状态
		}
		return sortedArrayToBSTAno(nums, 0, nums.size() - 1);
	}
	TreeNode* sortedArrayToBSTAno(vector<int>& nums, int i, int j) {
		if (i > j) {//退出状态
			return nullptr;
		}
		if (i == j) {//此范围就一个节点,直接创建返回即可
			return new TreeNode(nums[i]);
		}
		int mid = (i + j) / 2;//求出来的中点都靠左边
		//int mid = (i + j + 1) / 2; 求出来的中点都靠右侧
		//int mid = (i + j + rand.nextInt(2)) / 2; 随机选一个中点
		TreeNode* temp = new TreeNode(nums[mid]);//创建中间根节点
		temp->left = sortedArrayToBSTAno(nums, i, mid - 1);//连接左面
		temp->right = sortedArrayToBSTAno(nums, mid + 1, j);//连接右面
		return temp;//将拼凑好的节点返回回溯即可,去拼凑更上层的节点。
	}
};

(所有代码均已在力扣上运行无误)

经测试,该代码运行情况是(经过多次测试所得最短时间):

在这里插入图片描述

时空复杂度:

在这里插入图片描述

题目三要求:

在这里插入图片描述

整体思路 :贪心

1、观察题意,我们现在具体要移动到谁那里不知道,并且移动两次无消耗,移动一次1消耗,我么要知道,0到正无穷,可以看成是偶数和奇数构成的,相邻的奇数偶数数之间都相隔2,奇数和偶数相隔1,假设我们选择一个奇数位置,那么剩下的全部奇数位置到目标位置的消耗和为0,偶数位置都是1,那么总消耗就是偶数位置个数和,起始位置反之亦然。
2、所以综合上述观察,我们完全没必要纠结我们要把所有东西移动到那个位置,我们只需要知道奇数位置点和偶数位置点个数就行了,我现在要让整体消耗最小,所以我贪心的选择了二者中点数较多的一方作为移动过后目标位置。

具体代码

class Solution {
public:
	int minCostToMoveChips(vector<int>& position) {
		int n = position.size();
		int ans_one = 0;//偶数位置个数
		int ans_two = 0;//奇数位置个数
		for (int i = 0; i < n; i++) {//统计
			if (position[i] % 2 == 0) {
				ans_one++;
				continue;
			}
			ans_two++;
		}
		//偶数位置多,那么就移动到偶数位,答案就是奇数点个数
		//奇数位置多,那么就移动到奇数位,答案就是偶数点个数
		return min(ans_one, ans_two);
	}
};

(所有代码均已在力扣上运行无误)

经测试,该代码运行情况是(经过多次测试所得最短时间):

在这里插入图片描述

时间复杂度:
O(N):N指的是chips数组的数组长度,我们只需要遍历一遍数组即可。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

JLU_LYM

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值