返回转换后的单向链表的头节点。
注意:本题相对原题稍作改动
示例:
输入: [4,2,5,1,3,null,6,0]
输出: [0,null,1,null,2,null,3,null,4,null,5,null,6]
提示:
节点数量不会超过 100000。
来源:力扣(LeetCode)
链接: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
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
滑动窗口
class Solution {
public int[] shortestSeq(int[] big, int[] small) {
Map<Integer,Integer> window = new HashMap<>(); //window记录窗口内元素的情况
Set set = new HashSet<>(); //set作为查找表
for(int e : small)
set.add(e);
int[] res = {big.length,big.length};
int minLen = big.length + 1;
for(int l=0,r=0;r<big.length;r++) {
if(set.contains(big[r])) //考虑big[r]要不要进窗口【在set中的值才允许进入】
window.put(big[r],window.getOrDefault(big[r],0)+1);
while(window.size()==set.size()) { //当窗口符合要求,左边界收缩,注意要不要更新window
if(set.contains(big[l])) { //此时,需要更新window
int n = window.get(big[l]);
if(n==1) {
window.remove(big[l]); //。。。
if(r-l+1<minLen) { //看要不要更新答案
res[0] = l;
res[1] = r;
minLen = r-l+1;
}
}else {
window.put(big[l],n-1);
}
最后
最后为了帮助大家深刻理解Android相关知识点的原理以及面试相关知识,这里放上相关的我搜集整理的24套腾讯、字节跳动、阿里、百度2019-2021BAT 面试真题解析,我把大厂面试中常被问到的技术点整理成了视频和PDF(实际上比预期多花了不少精力),包知识脉络 + 诸多细节。
还有 高级架构技术进阶脑图 帮助大家学习提升进阶,也节省大家在网上搜索资料的时间来学习,也可以分享给身边好友一起学习。
Android 基础知识点
Java 基础知识点
Android 源码相关分析
常见的一些原理性问题
希望大家在今年一切顺利,进到自己想进的公司,共勉!
《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》,点击传送门,即可获取!
e(window.size()==set.size()) { //当窗口符合要求,左边界收缩,注意要不要更新window
if(set.contains(big[l])) { //此时,需要更新window
int n = window.get(big[l]);
if(n==1) {
window.remove(big[l]); //。。。
if(r-l+1<minLen) { //看要不要更新答案
res[0] = l;
res[1] = r;
minLen = r-l+1;
}
}else {
window.put(big[l],n-1);
}
最后
最后为了帮助大家深刻理解Android相关知识点的原理以及面试相关知识,这里放上相关的我搜集整理的24套腾讯、字节跳动、阿里、百度2019-2021BAT 面试真题解析,我把大厂面试中常被问到的技术点整理成了视频和PDF(实际上比预期多花了不少精力),包知识脉络 + 诸多细节。
还有 高级架构技术进阶脑图 帮助大家学习提升进阶,也节省大家在网上搜索资料的时间来学习,也可以分享给身边好友一起学习。
Android 基础知识点
Java 基础知识点
Android 源码相关分析
常见的一些原理性问题
[外链图片转存中…(img-cI1NcD3U-1715789720599)]
希望大家在今年一切顺利,进到自己想进的公司,共勉!
《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》,点击传送门,即可获取!