wy的leetcode刷题记录_Day58
声明
本文章的所有题目信息都来源于leetcode
如有侵权请联系我删掉!
时间:2022-12-2
前言
力扣每日一题简单模拟左右抵消和二叉平衡搜索树 1769. 移动所有球到每个盒子所需的最小操作数和108. 将有序数组转换为二叉搜索树
目录
- wy的leetcode刷题记录_Day58
- 声明
- 前言
- 1769. 移动所有球到每个盒子所需的最小操作数
- 题目介绍
- 思路
- 代码
- 收获
- 108. 将有序数组转换为二叉搜索树
- 题目介绍
- 思路
- 代码
- 收获
1769. 移动所有球到每个盒子所需的最小操作数
今天的每日一题是:1769. 移动所有球到每个盒子所需的最小操作数
题目介绍
有 n 个盒子。给你一个长度为 n 的二进制字符串 boxes ,其中 boxes[i] 的值为 ‘0’ 表示第 i 个盒子是 空 的,而 boxes[i] 的值为 ‘1’ 表示盒子里有 一个 小球。
在一步操作中,你可以将 一个 小球从某个盒子移动到一个与之相邻的盒子中。第 i 个盒子和第 j 个盒子相邻需满足 abs(i - j) == 1 。注意,操作执行后,某些盒子中可能会存在不止一个小球。
返回一个长度为 n 的数组 answer ,其中 answer[i] 是将所有小球移动到第 i 个盒子所需的 最小 操作数。
每个 answer[i] 都需要根据盒子的 初始状态 进行计算。
示例 1:
输入:boxes = “110”
输出:[1,1,3]
解释:每个盒子对应的最小操作数如下:
- 第 1个盒子:将一个小球从第 2 个盒子移动到第 1 个盒子,需要 1 步操作。
- 第 2 个盒子:将一个小球从第 1 个盒子移动到第 2个盒子,需要 1 步操作。
- 第 3 个盒子:将一个小球从第 1 个盒子移动到第 3 个盒子,需要 2 步操作。将一个小球从第 2
个盒子移动到第 3 个盒子,需要 1 步操作。共计 3 步操作。
示例 2:
输入:boxes = “001011”
输出:[11,8,5,4,3,4]
思路
方法一:双重循环:一道简单的模拟题:根据题意知道,我们通过两层循环,对于第i个需要返回的位置,我们将每个盒子遍历一遍,当第j个盒子装有小球的时候我们移动abs(j-1)个距离能将该小球移动到第i个盒子,以此类推
方法二:通过维护当前遍历盒子的左右装球盒子的个数及其上一次的操作数来判断这次的操作数,这次的操作数由上一次的操作数+左边的数量-右边的数量,因为向右移了一位之后左边的都需要多走一步,右边的需要少走一步,互相抵消后就是俩边的数量差了。每一次迭代要维护左右装球盒子的个数。
代码
class Solution {
public:
vector<int> minOperations(string boxes) {
int n = boxes.size();
vector<int> res(n);
for (int i = 0; i < n; i++) {
int sm = 0;
for (int j = 0; j < n; j++) {
if (boxes[j] == '1') {
sm += abs(j - i);
}
}
res[i] = sm;
}
return res;
}
};
进阶:
class Solution {
public:
vector<int> minOperations(string boxes) {
int n = boxes.size();
vector<int> res(n);
int left=boxes[0]-'0';
int right=0;
int operation=0;
for(int i=1;i<n;i++)
{
if(boxes[i]=='1')
{
right++;
operation+=i;
}
}
res[0]=operation;
for(int i=1;i<n;i++)
{
operation+=left-right;
if(boxes[i]=='1')
{
left++;
right--;
}
res[i]=operation;
}
return res;
}
};
收获
手速题
108. 将有序数组转换为二叉搜索树
108. 将有序数组转换为二叉搜索树
题目介绍
给你一个整数数组 nums ,其中元素已经按 升序 排列,请你将其转换为一棵 高度平衡 二叉搜索树。
高度平衡 二叉树是一棵满足「每个节点的左右两个子树的高度差的绝对值不超过 1 」的二叉树。
示例 1:
输入:nums = [-10,-3,0,5,9]
输出:[0,-3,9,-10,null,5]
解释:[0,-10,5,null,-3,null,9] 也将被视为正确答案:
示例 2:
输入:nums = [1,3]
输出:[3,1]
解释:[1,null,3] 和 [3,1] 都是高度平衡二叉搜索树。
思路
本题给出的数组是有序的,所以本题还是比较简单的,因为我们不仅要构造二叉搜索树并且还要确保其平衡,左右子树的高度差不能超过1,于是我们选择从数组的中间位置开始遍历,奇数就是中间,偶数不管你向上取整或者向下取整都是没问题的。从中间的位置遍历,我们根据此位置再将数组分为左区间和右区间分别对应当前节点的左子树和右子树,同理再找中间…直到区间中没有数。
代码
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
//TreeNode* ans;
TreeNode* sortedArrayToBST(vector<int>& nums) {
int n=nums.size();
TreeNode* ans=dfs(nums,0,n-1);
return ans;
}
TreeNode* dfs(vector<int>& nums,int left,int right)
{
// int n=nums.size();
if(left>right)
return nullptr;
int mid=left+(right-left)/2;
TreeNode *node=new TreeNode(nums[mid]);
// vector<int> nums_left;
// copy(nums.begin(),nums.begin()+mid,nums_left.begin());
// vector<int> nums_right;
// copy(nums.begin()+mid,nums.end(),nums_right.begin());
node->left=dfs(nums,left,mid-1);
node->right=dfs(nums,mid+1,right);
return node;
}
};
收获
掌握了平衡二叉树的基本概念,以及使用有序数组将其构造。