leetcode 中等难度 错题
有 n 个盒子。给你一个长度为 n 的二进制字符串 boxes ,其中 boxes[i] 的值为 '0' 表示第 i 个盒子是 空 的,而 boxes[i] 的值为 '1' 表示盒子里有 一个 小球。 在一步操作中,你可以将 一个 小球从某个盒子移动到一个与之相邻的盒子中。第 i 个盒子和第 j 个盒子相邻需满足 abs(i - j) == 1 。注意,操作执行后,某些盒子中可能会存在不止一个小球。 返回一个长度为 n 的数组 answer ,其中 answer[i] 是将所有小球移动到第 i 个盒子所需的 最小 操作数。 每个 answer[i] 都需要根据盒子的 初始状态 进行计算。 class Solution { public: vector<int> minOperations(string boxes) { int size=boxes.size(); vector<int> reslut(size); for(int i=0;i<size;i++) { if(boxes[i]=='1') { for(int j=0;j<size;j++) { reslut[j]+=abs(i-j); } } } return reslut; } };
如果一个十进制数字不含任何前导零,且每一位上的数字不是 0 就是 1 ,那么该数字就是一个 十-二进制数 。例如,101 和 1100 都是 十-二进制数,而 112 和 3001 不是。 给你一个表示十进制整数的字符串 n ,返回和为 n 的 十-二进制数 的最少数目。 示例 1: 输入:n = "32" 输出:3 解释:10 + 11 + 11 = 32 示例 2: 输入:n = "82734" 输出:8 示例 3: 输入:n = "27346209830709182346" 输出:9 class Solution { public: int minPartitions(string n) { int result=0; for(int i=0;i<n.size();i++) { if(n[i]-'0'>result) result=n[i]-'0'; } return result; } };
给你一个整数数组 arr 和一个整数值 target 。 请你在 arr 中找 两个互不重叠的子数组 且它们的和都等于 target 。可能会有多种方案,请你返回满足要求的两个子数组长度和的 最小值 。 请返回满足要求的最小长度和,如果无法找到这样的两个子数组,请返回 -1 。 来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/find-two-non-overlapping-sub-arrays-each-with-target-sum 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 思路 使用滑动窗口找出所有和为 target 的子数组 使用 multimap 按照长度保存 使用双循环依次遍历两个不同的子数组 31. 如果有交叉跳过,注意是按长度排的,要在前在后都判断 32. 记录最小值 33. 剪枝 答题 作者:ikaruga 链接:https://leetcode-cn.com/problems/find-two-non-overlapping-sub-arrays-each-with-target-sum/solution/find-two-by-ikaruga/ 来源:力扣(LeetCode) 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 class Solution { public: int minSumOfLengths(vector<int>& arr, int target) { multimap<int, int> data; int left=0; int sum=0; int right=0; while(right<arr.size()){ sum += arr[right]; right++; if (sum < target) continue; while(sum>target){ sum-=arr[left]; left++; } if(sum==target) { data.insert({right-left,left}); } } int result= INT_MAX; for(auto p1=data.begin();p1!=data.end();p1++) { if(p1->first*2>=result)break; auto p2=p1; while((++p2)!=data.end()) { if(p1->second < p2->second && p1->second + p1->first > p2->second) continue; if (p2->second < p1->second && p2->second + p2->first > p1->second) continue; result=min(result,p1->first+p2->first);//?????????? break;//map增序 } } if(result<INT_MAX)return result; return -1; } };
编写一个函数,不用临时变量,直接交换numbers = [a, b]中a与b的值。 class Solution { public: vector<int> swapNumbers(vector<int>& numbers) { numbers[0] ^= numbers[1]; numbers[1] ^= numbers[0]; numbers[0] ^= numbers[1]; return numbers; } };
给你两棵二叉树,原始树 original 和克隆树 cloned,以及一个位于原始树 original 中的目标节点 target。 其中,克隆树 cloned 是原始树 original 的一个 副本 。 请找出在树 cloned 中,与 target 相同 的节点,并返回对该节点的引用(在 C/C++ 等有指针的语言中返回 节点指针,其他语言返回节点本身)。 注意: 你 不能 对两棵二叉树,以及 target 节点进行更改。 只能 返回对克隆树 cloned 中已有的节点的引用。 进阶:如果树中允许出现值相同的节点,你将如何解答? 来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/find-a-corresponding-node-of-a-binary-tree-in-a-clone-of-that-tree 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 /** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */ class Solution { public: TreeNode* getTargetCopy(TreeNode* original, TreeNode* cloned, TreeNode* target) { if(original!=NULL && target==original) return cloned; if(original==NULL)return NULL; TreeNode * left =getTargetCopy( original->left,cloned->left,target); TreeNode * right=getTargetCopy(original->right,cloned->right,target); if (left!=NULL)return left; return right; } };
存在一个长度为 n 的数组 arr ,其中 arr[i] = (2 * i) + 1 ( 0 <= i < n )。 一次操作中,你可以选出两个下标,记作 x 和 y ( 0 <= x, y < n )并使 arr[x] 减去 1 、arr[y] 加上 1 (即 arr[x] -=1 且 arr[y] += 1 )。最终的目标是使数组中的所有元素都 相等 。题目测试用例将会 保证 :在执行若干步操作后,数组中的所有元素最终可以全部相等。 给你一个整数 n,即数组的长度。请你返回使数组 arr 中所有元素相等所需的 最小操作数 。 class Solution { public: int minOperations(int n) { return n * n / 4; } };
括号。设计一种算法,打印n对括号的所有合法的(例如,开闭一一对应)组合。 说明:解集不能包含重复的子集。 例如,给出 n = 3,生成结果为: [ "((()))", "(()())", "(())()", "()(())", "()()()" ] class Solution { vector<string> ans; public: vector<string> generateParenthesis(int n) { help(n, n, ""); return ans; } void help(int l, int r, string a) { if (l == 0 && r == 0) { ans.emplace_back(a); return; } if (l != 0) help(l - 1, r, a + '('); if (l < r) help(l, r - 1, a + ')'); } };
给你一棵二叉树的根节点 root ,请你返回 层数最深的叶子节点的和 。 我们可以使用深度优先搜索的方法解决这个问题。 我们从根节点开始进行搜索,在搜索的同时记录当前节点的深度 dep。我们维护两个全局变量 maxdep 和 total,其中 maxdep 表示搜索到的节点的最大深度,total 表示搜索到的深度等于 maxdep 的节点的权值之和。 当我们搜索到一个新的节点 x 时,会有以下三种情况: 节点 x 的深度 dep 小于 maxdep,那么我们可以忽略节点 x,继续进行搜索; 节点 x 的深度 dep 等于 maxdep,那么我们将节点 x 的权值添加到 total 中; 节点 x 的深度 dep 大于 maxdep,此时我们找到了一个深度更大的节点,因此需要将 maxdep 置为 dep,并将 total 置为节点 x 的权值。 在深度优先搜索结束之后,深度最大的叶子节点的权值之和即存储在 total 中。 class Solution { private: int maxdep = -1; int total = 0; public: void dfs(TreeNode* node, int dep) { if (!node) { return; } if (dep > maxdep) { maxdep = dep; total = node->val; } else if (dep == maxdep) { total += node->val; } dfs(node->left, dep + 1); dfs(node->right, dep + 1); } int deepestLeavesSum(TreeNode* root) { dfs(root, 0); return total; } };
给你一个字符串表达式 s ,请你实现一个基本计算器来计算并返回它的值。 整数除法仅保留整数部分。 输入:s = "3+2*2" 输出:7 方法一:栈 思路 由于乘除优先于加减计算,因此不妨考虑先进行所有乘除运算,并将这些乘除运算后的整数值放回原表达式的相应位置,则随后整个表达式的值,就等于一系列整数加减后的值。 基于此,我们可以用一个栈,保存这些(进行乘除运算后的)整数的值。对于加减号后的数字,将其直接压入栈中;对于乘除号后的数字,可以直接与栈顶元素计算,并替换栈顶元素为计算后的结果。 具体来说,遍历字符串 ss,并用变量 \textit{preSign}preSign 记录每个数字之前的运算符,对于第一个数字,其之前的运算符视为加号。每次遍历到数字末尾时,根据 \textit{preSign}preSign 来决定计算方式: 加号:将数字压入栈; 减号:将数字的相反数压入栈; 乘除号:计算数字与栈顶元素,并将栈顶元素替换为计算结果。 代码实现中,若读到一个运算符,或者遍历到字符串末尾,即认为是遍历到了数字末尾。处理完该数字后,更新 \textit{preSign}preSign 为当前遍历的字符。 遍历完字符串 ss 后,将栈中元素累加,即为该字符串表达式的值。
class Solution {
public:
int calculate(string s) {
stack<int> tmp;
char preSign='+';
for(int i=0;i<s.length();i++)
{
if(s[i]==' ')continue;
int d=s[i]-'0';
if(d>=0&&d<=9)
{
if(preSign=='+')
{
if(i>0&&s[i-1]-'0'>=0&&s[i-1]-'0'<=9)
{
int b=tmp.top()*10+d;
tmp.pop();
tmp.push(b);
}else
tmp.push(d);
}else if(preSign=='-')
{
if(i>0&&s[i-1]-'0'>=0&&s[i-1]-'0'<=9)
{
int b=tmp.top()*10-d;
tmp.pop();
tmp.push(b);
}else
tmp.push(-d);
}else if(preSign=='*')
{
int pre=tmp.top();
tmp.pop();
tmp.push(pre*d);
}else if(preSign=='/')
{
int pre=tmp.top();
tmp.pop();
tmp.push(pre/d);
}
}else
{
preSign=s[i];
}
}
int result=0;
while(!tmp.empty())
{
result+=tmp.top();
tmp.pop();
}
return result;
}
};
/** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */ class Solution { public: int sumEvenGrandparent(TreeNode* root) { return MyFunc(false,false,root); } int MyFunc(bool pre,bool prepre,TreeNode * root) { if(root==NULL)return 0; int result=0; if(prepre)result+=root->val; if((root->val%2)==0) { result+= MyFunc(true ,pre,root->left)+MyFunc(true,pre,root->right); }else { result+= MyFunc(false ,pre,root->left)+MyFunc(false,pre,root->right); } return result; } };
使用一个bool数组来表示某个字符是否已经被使用了,如果没有被使用就尝试把这个字符加入结果中,然后递归,之后取消加入的这个字符,这就是所谓的回溯。用一颗树来表示的话就是不断向下深入然后在向上返回的过程。 无重复字符串的排列组合。编写一种方法,计算某字符串的所有排列组合,字符串每个字符均不相同。 示例1: 输入:S = "qwe" 输出:["qwe", "qew", "wqe", "weq", "ewq", "eqw"] 使用一个bool数组来表示某个字符是否已经被使用了,如果没有被使用就尝试把这个字符加入结果中,然后递归,之后取消加入的这个字符,这就是所谓的回溯。用一颗树来表示的话就是不断向下深入然后在向上返回的过程。 class Solution { public: vector<string> permutation(string S) { vector<bool> used(S.size(), false); vector<string> res; string path; backtrack(S, res, path, used); return res; } void backtrack(string& S, vector<string>& res, string& path, vector<bool>& used) { if ( S.size() == path.size() ) { res.emplace_back(path); return; } for ( int i = 0; i < S.size(); ++i ) { if ( !used[i] ) { path.push_back(S[i]); used[i] = true; backtrack(S, res, path, used); path.pop_back(); used[i] = false; } } } };
有一个二维矩阵 A 其中每个元素的值为 0 或 1 。 移动是指选择任一行或列,并转换该行或列中的每一个值:将所有 0 都更改为 1,将所有 1 都更改为 0。 在做出任意次数的移动后,将该矩阵的每一行都按照二进制数来解释,矩阵的得分就是这些数字的总和。 返回尽可能高的分数。 示例: 输入:[[0,0,1,1],[1,0,1,0],[1,1,0,0]] 输出:39 解释: 转换为 [[1,1,1,1],[1,0,0,1],[1,1,1,1]] 0b1111 + 0b1001 + 0b1111 = 15 + 9 + 15 = 39 class Solution { public: int matrixScore(vector<vector<int>>& A) { int m = A.size(), n = A[0].size(); int ret = m * (1 << (n - 1)); for (int j = 1; j < n; j++) { int nOnes = 0; for (int i = 0; i < m; i++) { if (A[i][0] == 1) { nOnes += A[i][j]; } else { nOnes += (1 - A[i][j]); // 如果这一行进行了行反转,则该元素的实际取值为 1 - A[i][j] } } int k = max(nOnes, m - nOnes); ret += k * (1 << (n - j - 1)); } return ret; } };

浙公网安备 33010602011771号