Leetcode面T17(11-20)树(1),记录你曾经的面试经历

先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7

深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
img
img
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Android开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以添加V获取:vip204888 (备注Android)
img

正文

链接:https://leetcode-cn.com/problems/binode-lcci

著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

简单的递归,借用一个先驱节点当做链表一样

/**

  • Definition for a binary tree node.

  • public class TreeNode {

  • int val;
    
  • TreeNode left;
    
  • TreeNode right;
    
  • TreeNode(int x) { val = x; }
    
  • }

*/

class Solution {

TreeNode f;

public TreeNode convertBiNode(TreeNode root) {

f = new TreeNode(Integer.MIN_VALUE);

TreeNode pre = f;

dfs(root);

return pre.right;

}

public void dfs(TreeNode root) {

if (root == null) return;

dfs(root.left);

f.right = root;

root.left = null;

f = f.right;

dfs(root.right);

}

}

Q17.13 恢复空格

哦,不!你不小心把一个长篇文章中的空格、标点都删掉了,并且大写也弄成了小写。像句子"I reset the computer. It still didn’t boot!“已经变成了"iresetthecomputeritstilldidntboot”。在处理标点符号和大小写之前,你得先把它断成词语。当然了,你有一本厚厚的词典dictionary,不过,有些词没在词典里。假设文章用sentence表示,设计一个算法,把文章断开,要求未识别的字符最少,返回未识别的字符数。

注意:本题相对原题稍作改动,只需返回未识别的字符数

示例:

输入:

dictionary = [“looked”,“just”,“like”,“her”,“brother”]

sentence = “jesslookedjustliketimherbrother”

输出: 7

解释: 断句后为"jess looked just like tim her brother",共7个未识别字符。

提示:

0 <= len(sentence) <= 1000

dictionary中总字符数不超过 150000。

你可以认为dictionary和sentence中只包含小写字母。

来源:力扣(LeetCode)

链接:https://leetcode-cn.com/problems/re-space-lcci

著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路:直接求最少匹配的字符数比较复杂,所以反过来我们求能匹配的最大字符数。这道题相当于一个 完全0-1背包问题,背包容量为字符串长度,物品(字典中的单词)数量没有限制。我们要做的就是尽可能的填满这个背包。

1.定义状态: dp[i][j] 表示字符串(0i),字典(0i)的状态下,匹配的最大字符数。

2.状态转移:从背包末尾开始考虑:

当单词能塞进背包末尾的时候,即 sentence.substring(i-len,i) 与 当前单词相等,len 为单词长度。此时单词有两种状态,塞进背包,和不塞进背包,记住单词可以重复取用,取这两种状态的最大值:dp[i][j] = max(dp[i-len][j]+len,dp[i][j-1])。

当单词不能塞进背包末尾的时候,取字符串(0~i-1)与当前单词的组合dp[i-1][j],和当前字符串与前一个单词组合dp[i][j-1]这两种组合的最大值。即:dp[i][j] = max(dp[i-1][j],dp[i][j-1]).

3.返回值:sentence.length() - dp[m][n];

4.状态压缩:二维dp数组可以压缩为一维数组。

5.如果有帮到您,请不吝啬点赞~

class Solution {

public int respace(String[] dictionary, String sentence) {

int m = sentence.length();

int[] dp = new int[m+1];

for(int i=1;i<=m;i++){ //外层循环字符串

for(String word:dictionary){ //内层循环字典

int len = word.length();

if(i >= len && word.equals(sentence.substring(i-len,i))){

dp[i] = Math.max(dp[i],dp[i-len]+len); //状态转移

}else{

dp[i] = Math.max(dp[i],dp[i-1]);

}

}

}

return m-dp[m];

}

}

Q17.14 最小K个数

设计一个算法,找出数组中最小的k个数。以任意顺序返回这k个数均可。

示例:

输入: arr = [1,3,5,7,2,4,6,8], k = 4

输出: [1,2,3,4]

提示:

0 <= len(arr) <= 100000

0 <= k <= min(100000, len(arr))

来源:力扣(LeetCode)

链接:https://leetcode-cn.com/problems/smallest-k-lcci

著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

快速排序递归版

class Solution {

public int[] smallestK(int[] arr, int k) {

select(arr, 0, arr.length - 1, k);

int[] ans = new int[k];

System.arraycopy(arr, 0, ans, 0, k);

return ans;

}

public void select(int[] arr, int p, int q, int k) {

if (p >= q) return;

int l = p, r = q;

int m = arr[p];

while (l < r) {

while (l < r && arr[r] >= m) {

r–;

}

arr[l] = arr[r];

while (l < r && arr[l] <= m) {

l++;

}

arr[r] = arr[l];

}

arr[l] = m;

int t = l - p + 1;

if (t == k) return;

if (t < k) {

select(arr, l + 1, q, k - t);

} else {

select(arr, p, l - 1, k);

}

}

}

Q17.15 最长单词

给定一组单词words,编写一个程序,找出其中的最长单词,且该单词由这组单词中的其他单词组合而成。若有多个长度相同的结果,返回其中字典序最小的一项,若没有符合要求的单词则返回空字符串。

示例:

输入: [“cat”,“banana”,“dog”,“nana”,“walk”,“walker”,“dogwalker”]

输出: “dogwalker”

解释: "dogwalker"可由"dog"和"walker"组成。

提示:

0 <= len(words) <= 200

1 <= len(words[i]) <= 100

来源:力扣(LeetCode)

链接:https://leetcode-cn.com/problems/longest-word-lcci

著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路简单:

按照长度降序排序,如果长度相等就按照字典序排序。这样的话如果每个单词都是组合单词,那么最前面的单词就是题目要求的返回单词。

遍历排序后的单词数组,如果是复合单词就返回

复合单词检测思路: 目标单词的前i个字母是单词列表里面的单词 && 剩下的字母是组合单词

class Solution {

// 检测word是否是由set里面的单词组成

private boolean isComposeWord(Set set, String word) {

if (word.length() == 0) {

return true;

}

for (int i = 0; i < word.length(); i++) {

if (set.contains(word.substring(0, i + 1)) && isComposeWord(set, word.substring(i + 1))) {

return true;

}

}

return false;

}

public String longestWord(String[] words) {

// 将单词列表按照长度降序,长度相同按照字典序

Arrays.sort(words, (o1, o2) -> {

if (o1.length() == o2.length()) {

return o1.compareTo(o2);

} else {

return Integer.compare(o2.length(), o1.length());

}

});

// 把数组做成set,提高检测的效率

Set set = new HashSet<>(Arrays.asList(words));

// 遍历检测当前单词是不是组合单词,是的话直接返回

for (String word :words ) {

set.remove(word);

if (isComposeWord(set, word)) {

return word;

}

set.add(word);

}

return “”;

}

}

Q17.16 按摩师

一个有名的按摩师会收到源源不断的预约请求,每个预约都可以选择接或不接。在每次预约服务之间要有休息时间,因此她不能接受相邻的预约。给定一个预约请求序列,替按摩师找到最优的预约集合(总预约时间最长),返回总的分钟数。

注意:本题相对原题稍作改动

示例 1:

输入: [1,2,3,1]

输出: 4

解释: 选择 1 号预约和 3 号预约,总时长 = 1 + 3 = 4。

示例 2:

输入: [2,7,9,3,1]

输出: 12

解释: 选择 1 号预约、 3 号预约和 5 号预约,总时长 = 2 + 9 + 1 = 12。

示例 3:

输入: [2,1,4,5,3,1,1,3]

输出: 12

解释: 选择 1 号预约、 3 号预约、 5 号预约和 8 号预约,总时长 = 2 + 4 + 3 + 3 = 12。

来源:力扣(LeetCode)

链接:https://leetcode-cn.com/problems/the-masseuse-lcci

著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

递推方程:dp[i] = max(dp[i - 1], dp[i - 2] + nums[i])

class Solution {

public int massage(int[] nums) {

int n = nums.length;

if (n == 0) {

return 0;

}

if (n == 1) {

return nums[0];

}

int[] dp = new int[n];

dp[0] = nums[0];

dp[1] = Math.max(nums[0], nums[1]);

for (int i = 2; i < n; i++) {

dp[i] = Math.max(dp[i - 1], dp[i - 2] + nums[i]);

}

return dp[n - 1];

}

}

Q17.17 多次搜索

给定一个较长字符串big和一个包含较短字符串的数组smalls,设计一个方法,根据smalls中的每一个较短字符串,对big进行搜索。输出smalls中的字符串在big里出现的所有位置positions,其中positions[i]为smalls[i]出现的所有位置。

示例:

输入:

big = “mississippi”

smalls = [“is”,“ppi”,“hi”,“sis”,“i”,“ssippi”]

输出: [[1,4],[8],[],[3],[1,4,7,10],[5]]

提示:

0 <= len(big) <= 1000

0 <= len(smalls[i]) <= 1000

smalls的总字符数不会超过 100000。

你可以认为smalls中没有重复字符串。

所有出现的字符均为英文小写字母。

来源:力扣(LeetCode)

链接:https://leetcode-cn.com/problems/multi-search-lcci

著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

public int[][] multiSearch(String big, String[] smalls) {

if (smalls == null || big == null || smalls.length == 0) return new int[0][];

List<List> tempRes = new LinkedList<>();

for (String small : smalls) {

List tmp = new LinkedList<>();

if (small.length() == 0) {

tempRes.add(tmp);

continue;

}

int index = 0;

while (index < big.length() && big.indexOf(small, index) != -1) {

int pos = big.indexOf(small, index);

tmp.add(pos);

index = pos + 1;

}

tempRes.add(tmp);

}

int[][] res = new int[tempRes.size()][];

for (int i = 0; i < res.length; i++) {

int[] ints = new int[tempRes.get(i).size()];

for (int i1 = 0; i1 < ints.length; i1++) {

ints[i1] = tempRes.get(i).get(i1);

}

res[i] = ints;

}

return res;

}

Q17.18 最短超串

假设你有两个数组,一个长一个短,短的元素均不相同。找到长数组中包含短数组所有的元素的最短子数组,其出现顺序无关紧要。

返回最短子数组的左端点和右端点,如有多个满足条件的子数组,返回左端点最小的一个。若不存在,返回空数组。

示例 1:

输入:

big = [7,5,9,0,2,1,3,5,7,9,1,1,5,8,8,9,7]

small = [1,5,9]

输出: [7,10]

示例 2:

输入:

big = [1,2,3]

small = [4]

输出: []

提示:

big.length <= 100000

1 <= small.length <= 100000

来源:力扣(LeetCode)

链接:https://leetcode-cn.com/problems/shortest-supersequence-lcci

著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

最后

感谢您的阅读,在文末给大家准备一个福利。本人从事Android开发已经有十余年,算是一名资深的移动开发架构师了吧。根据我的观察发现,对于很多初中级Android工程师而言,想要提升技能,往往是自己摸索成长,不成体系的学习效果低效漫长且无助。

所以在此将我十年载,从萌新小白一步步成长为Android移动开发架构师的学习笔记,从Android四大组件到手写实现一个架构设计,我都有一一的对应笔记为你讲解。

当然我也为你们整理好了百度、阿里、腾讯、字节跳动等等互联网超级大厂的历年面试真题集锦。这也是我这些年来养成的习惯,一定要学会把好的东西,归纳整理,然后系统的消化吸收,这样才能极大的提高学习效率和成长进阶。碎片、零散化的东西,我觉得最没有价值的。就好比你给我一张扑克牌,我只会觉得它是一张废纸,但如果你给我一副扑克牌,它便有了它的价值。这和我们收集资料就要收集那些系统化的,是一个道理。

最后,赠与大家一句诗,共勉!

不驰于空想,不骛于虚声。不忘初心,方得始终。

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip204888 (备注Android)
img

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

已经有十余年,算是一名资深的移动开发架构师了吧。根据我的观察发现,对于很多初中级Android工程师而言,想要提升技能,往往是自己摸索成长,不成体系的学习效果低效漫长且无助。

所以在此将我十年载,从萌新小白一步步成长为Android移动开发架构师的学习笔记,从Android四大组件到手写实现一个架构设计,我都有一一的对应笔记为你讲解。

当然我也为你们整理好了百度、阿里、腾讯、字节跳动等等互联网超级大厂的历年面试真题集锦。这也是我这些年来养成的习惯,一定要学会把好的东西,归纳整理,然后系统的消化吸收,这样才能极大的提高学习效率和成长进阶。碎片、零散化的东西,我觉得最没有价值的。就好比你给我一张扑克牌,我只会觉得它是一张废纸,但如果你给我一副扑克牌,它便有了它的价值。这和我们收集资料就要收集那些系统化的,是一个道理。

[外链图片转存中…(img-jCIFzqVK-1713265411391)]

最后,赠与大家一句诗,共勉!

不驰于空想,不骛于虚声。不忘初心,方得始终。

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip204888 (备注Android)
[外链图片转存中…(img-5to7z31t-1713265411391)]

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 27
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值