北美大厂8月第一周算法面试真题汇总
发布于 2021-08-05 13:11 ,所属分类:试题库考试资料大全
应广大同学们的需求,我们将定期整理各大厂最新的面试题题解,由我们【上岸算法】资深的老师给大家进行分析讲解,帮助大家实时掌握最新的面试动态,早日上岸!
题目描述:Remove Invalid Parentheses
s
that contains parentheses and letters, remove the minimum number of invalid parentheses to make the input string valid.Example 1 :
Input: s = "()())()"
Output: ["(())()","()()()"]
Example 2:
Input: s = "(a)())()"
Output: ["(a())()","(a)()()"]
题 解
预处理判断出非法左右括号的个数,需要注意的是后出现的右括号是可以抵消一个先出现的左括号。然后根据左右括号非法的个数枚举每一个可以消除的点尝试消除。注意若消除一个左括号可以达到合法,但是存在多个连续的左括号的情况消除任意一个都是一样的结果,因此必须使用跳跃性dfs来实现跳过重复情况的操作。
参 考 代 码
class Solution {
public List<String> removeInvalidParentheses(String s) {
List<String> result = new ArrayList<>();
int[] res = getLeftAndRightCount(s);
int leftCount = res[0];
int rightCount = res[1];
dfs(s, leftCount, rightCount, 0, result);
return result;
}
// 最小的移除次数肯定为leftCount + rightCount
public void dfs(String s, int leftCount, int rightCount, int index,
List<String> result) {
// dfs 出口
if (leftCount == 0 && rightCount == 0 && isValid(s)) {
result.add(s);
}
for (int i = index; i < s.length(); i++) {
// 连续相同的字符消除任意一个都是一样的情况,需要跳过
if (i > index && s.charAt(i) == s.charAt(i - 1)) {
continue;
}
// 若左括号多则尝试消除左括号
if (leftCount > 0 && s.charAt(i) == '(') {
String newStr = s.substring(0, i) + s.substring(i + 1);
dfs(newStr, leftCount - 1, rightCount, i, result);
}
// 若右括号多则尝试消除左括号
if (rightCount > 0 && s.charAt(i) == ')') {
String newStr = s.substring(0, i) + s.substring(i + 1);
dfs(newStr, leftCount, rightCount - 1, i, result);
}
}
}
// 若当前左右括号计数都为0则表示表达式合法
public boolean isValid(String s) {
int[] res = getLeftAndRightCount(s);
return res[0] == 0 && res[1] == 0 ;
}
// 遍历计算左右括号的总数,先左后右可以做消除
public int[] getLeftAndRightCount(String s) {
int leftCount = 0, rightCount = 0;
int[] counts = new int[2];
for (int i = 0; i < s.length(); i++) {
if (s.charAt(i) == '(') {
leftCount++;
}
// 碰到右括号的时候,判断是否可以消除左括号
else if(s.charAt(i) == ')') {
if (leftCount > 0) {
leftCount --;
}
else {
rightCount++;
}
}
}
counts[0] = leftCount;
counts[1] = rightCount;
return counts;
}
}
题目描述:Count of Range Sum
Given an integer array nums
and two integers lower
and upper
, return the number of range sums that lie in[lower, upper]
inclusive.
Range sum S(i, j)
is defined as the sum of the elements in nums
between indices i
and j
inclusive, where i <= j
.
Example 1 :
Input: nums = [-2,5,-1], lower = -2, upper = 2
Output: 3
Explanation: The three ranges are: [0,0], [2,2], and [0,2] and their respective sums are: -2, -1, 2.
Example 2:
Input: nums = [0], lower = 0, upper = 0
Output: 1
题 解
这题可以使用前缀和+归并排序的解法实现更加容易理解;
这边介绍树状数组解法,详情见注释,利用树状数组记录的是具体某一个值得个数,快速求得小于等于某值的所有个数总和。
参 考 代 码
class Solution {
static class BinaryIndexedTree {
private final int[] data;
private final int size;
public BinaryIndexedTree(int size) {
data = new int[size];
this.size = size;
}
/**
* BIT indexes: [0, 1, 2, ..., pos, pos + 1, ..., size - 1]
* ↑
* update position
*/
public void update(int pos, int delta) {
pos += 1;
for (int i = pos; i <= size; i += i & -i) {
data[i - 1] += delta;
}
}
/**
* BIT indexes: [0, 1, 2, ..., pos, pos + 1, ..., size - 1]
* ↑ ↑
* query range:[left right]
*/
public int query(int pos) {
pos += 1;
int result = 0;
for (int i = pos; i > 0; i -= i & -i) {
result += data[i - 1];
}
return result;
}
}
public int countRangeSum(int[] nums, int lower, int upper) {
// construct the sums array
long[] sums = new long[nums.length + 1];
sums[0] = 0;
for (int i = 0; i < nums.length; i++) {
sums[i + 1] = sums[i] + nums[i];
}
// prepare sorted sums for numberToIndex
long[] sortedNumbers = Arrays.copyOf(sums, sums.length);
Arrays.sort(sortedNumbers);
int result = 0;
BinaryIndexedTree BIT = new BinaryIndexedTree(sortedNumbers.length);
// 遍历的顺序是有sum[i]遍历,因此在以sum[i]为基础计算的时候,sum[i]之前的元素已经被更新到BIT中
// 基于排好序的sortedNumbers的下标建立树状数组
// 树状数组中 data[i] 表示数组 sum 中已经加入到BIT中的元素小于等于sum[i] 的个数有data[i]个
for (int i = 0; i < sums.length; ++i) {
// 区间值要在 [lower <= sum[i] - sum[?] <= upper]
// 因此 sum[?] <= sum[i] - lower sum[?] >= sum[i] - upper
// 所以小于等于 sum[i] - lower 的个数,减去 sum[i] - upper - 1 的个数,就是符合条件的个数
result += BIT.query(numberToIndex(sortedNumbers, sums[i] - lower)) - BIT.query(numberToIndex(sortedNumbers, sums[i] - upper - 1));
// 更新树状数组当中关联位置都 + 1
BIT.update(numberToIndex(sortedNumbers, sums[i]), 1);
}
return result;
}
/**
* find the last element no larger than `target`
*/
public int numberToIndex(long[] sortedNumbers, long target) {
int start = 0, end = sortedNumbers.length - 1;
while (start + 1 < end) {
int mid = start + (end - start) / 2;
if (sortedNumbers[mid] <= target) {
start = mid;
} else {
end = mid;
}
}
if (sortedNumbers[end] <= target) return end;
if (sortedNumbers[start] <= target) return start;
return -1;
}
}
题目描述
Given `n` orders, each order consist in pickup and delivery services.
Count all valid pickup/delivery possible sequences such that delivery(i) is always after of pickup(i).
Since the answer may be too large, return it modulo 10^9 + 7.
Input: n = 1
Output: 1
Explanation: Unique order (P1, D1), Delivery 1 always is after of Pickup 1.
Input: n = 2
Output: 6
Explanation: All possible orders:
(P1,P2,D1,D2), (P1,P2,D2,D1), (P1,D1,P2,D2), (P2,P1,D1,D2), (P2,P1,D2,D1) and (P2,D2,P1,D1).
This is an invalid order (P1,D2,P2,D1) because Pickup 2 is after of Delivery 2.
题 解
每一个物品有取货送货两个操作,且送货必须在取货之后;针对于 n 个物品,最终一工会产生 2 * n 个操作。若此时再加入第 n + 1 个物品,相当于多了 2 步操作,我们需要计算的是这 2 步操作可以穿插在哪些操作中。很容易通过推导得出取货操作可以穿插在 2 * n + 1 个地方,对应每一种穿插位置,送货穿插的位置依次为 1, 2, 3, 4, ....., 2 * n + 1。
参 考 代 码
class Solution {
public int countOrders(int n) {
int mod = 1000000007;
long[] dp = new long[n + 1];
if (n == 1) {
return 1;
}
if (n == 2) {
return 6;
}
dp[1] = 1L;
dp[2] = 6L;
// 推导公式
for (int i = 3; i <= n; i++) {
int insertPoints = (i - 1) * 2 + 1;
// 当前新加入的物品可以穿插的取货送货的组合数
long count = (1 + insertPoints) * insertPoints / 2;
dp[i] = (dp[i - 1] * count) % mod;
}
return (int)dp[n];
}
}
题目描述:Number of Good Leaf Nodes Pairs
Given the root
of a binary tree and an integer distance
. A pair of two different leaf nodes of a binary tree is said to be good if the length of the shortest path between them is less than or equal to distance
.
Example 1 :
Input: root = [1,2,3,null,4], distance = 3
Output: 1
Explanation: The leaf nodes of the tree are 3 and 4 and the length of the shortest path between them is 3. This is the only good pair.
Example 2 :
Input: root = [1,2,3,4,5,6,7], distance = 3
Output: 2
Explanation: The good pairs are [4,5] and [6,7] with shortest path = 2. The pair [4,6] is not good because the length of ther shortest path between them is 4.
题 解
分治法计算当前距离当前root节点的叶子节点满足条件的个数,若距离当前叶子节点距离为 L1 的左子树叶子节点个数有 n 个,右子树距离当前节点为 L2 的叶子节点个数有 m 个,若 L1 + L2 < d,则有效的叶子对为 n * m。使用 Map 来记录当前 root 节点左右子树的叶子节点距离及个数信息。
参 考 代 码
class Solution {
int res = 0;
public int countPairs(TreeNode root, int distance) {
if (root == null) {
return 0;
}
dfs(root, distance);
return res;
}
private Map<Integer, Integer> dfs(TreeNode node, int d) {
Map<Integer, Integer> disToCount = new HashMap<>();
if (node == null) {
return disToCount;
}
if (node.left == null && node.right == null) {
disToCount.put(1, 1);
}
// divide 分别计算左右子树的距离和节点个数信息
Map<Integer, Integer> leftInfo = dfs(node.left, d);
Map<Integer, Integer> rightInfo = dfs(node.right, d);
// conquer 在满足距离的情况下计算合法的叶子对数
for (int lDis : leftInfo.keySet()) {
for (int rDis : rightInfo.keySet()) {
if (rDis <= d - lDis) {
res += leftInfo.get(lDis) * rightInfo.get(rDis);
}
}
// 若距离当前root节点的距离为超过 d - 1, 说明还能再往当前root的父亲走过,因此距离 + 1
if (lDis + 1 < d) {
disToCount.put(lDis + 1, leftInfo.get(lDis));
}
}
// 右子树的判断也是一样
for (int rDis : rightInfo.keySet()) {
if (rDis + 1 < d) {
// 这边因为Map中记录的当前root的父亲,因此对于当前的disToCount,记录的整个当前root的子树
// 而有些距离在计算left的时候已经被更新过了
disToCount.put(rDis + 1, rightInfo.get(rDis) + disToCount.getOrDefault(rDis + 1, 0));
}
}
return disToCount;
}
}
杭州上岸算法网络科技有限公司
上岸算法网络科技有限公司是一家致力于用高质量,高互动性小班课程来帮助学生更好的在就业市场中定位以及求职的公司。我们以顶级的课程质量,高互动性的教学方式以及独特的小班教学模式来帮助学生更快的跨过求职的鸿沟,用最高效,经济,合理的方式帮助更多学生快速找到梦寐以求的工作。
玩转算法面试 从真题到思维全面提升算法思维
玩转算法面试 从真题到思维全面提升算法思维
Hadoop全新实战视频教程 Hadoop全新力作 徐培成老师Hadoop14天课程---第一周部分
Hadoop全新实战视频教程 Hadoop全新力作 徐培成老师Hadoop14天课程---第一周部分
【百度云】【事业单位资料包】事业面试真题汇总
【百度云】【事业单位资料包】事业面试真题汇总
【百度云】35套托福阅读考试真题汇总
【百度云】35套托福阅读考试真题汇总
小升初真题汇总
小升初真题汇总
【0粉开播】最新快手无人直播带货,一周出单
【0粉开播】最新快手无人直播带货,一周出单
AMC8初中基础能力历年真题及答案全套真题-百度一下载
AMC8初中基础能力历年真题及答案全套真题-百度一下载
一周进步:新媒体公众号运营课程
一周进步:新媒体公众号运营课程
【百度云】教师招聘面试 结构化面试通关班10讲结构化面试真题
【百度云】教师招聘面试 结构化面试通关班10讲结构化面试真题
高考生物 煜姐 周芳煜 二轮复习-真题详解
高考生物 煜姐 周芳煜 二轮复习-真题详解
周芳煜高一生物必修一
周芳煜高一生物必修一
【百度云】托福英语阅读十年真题134套汇总
【百度云】托福英语阅读十年真题134套汇总
一周学会Node.js开发电影微信公众号
一周学会Node.js开发电影微信公众号
传智播客张鹏带你一周hold住html+css
传智播客张鹏带你一周hold住html+css
全新Linux精品课程猿课CTO阿铭一周带你成Linux大神
全新Linux精品课程猿课CTO阿铭一周带你成Linux大神
全新Linux精品课程猿课CTO阿铭一周带你成Linux大神
全新Linux精品课程猿课CTO阿铭一周带你成Linux大神
尚硅谷Java面试题第一季 .
尚硅谷Java面试题第一季 .
某课266元-从真题到思维全面提升算法思维 - 难度中级
某课266元-从真题到思维全面提升算法思维 - 难度中级
算法面试通关40讲
算法面试通关40讲
算法面试通关40讲
算法面试通关40讲
高中生物 周芳煜 煜姐生物 2022年高考二三轮联报 真题全解
高中生物 周芳煜 煜姐生物 2022年高考二三轮联报 真题全解
2022高考真题原卷 解析卷 word文档
2022高考真题原卷 解析卷 word文档
全国历年中考真题试卷一网打尽
全国历年中考真题试卷一网打尽
周永亮高一数学2022寒假尖端班8讲完结
周永亮高一数学2022寒假尖端班8讲完结
中考真题分类汇编
中考真题分类汇编
相关资源