Leetcode(周赛):移除字母异位词5234,最大连续楼层数6064
Posted Dream_it_possible!
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Leetcode(周赛):移除字母异位词5234,最大连续楼层数6064相关的知识,希望对你有一定的参考价值。
目录
一、字母异位词(简单)
给你一个下标从 0 开始的字符串 words ,其中 words[i] 由小写英文字符组成。
在一步操作中,需要选出任一下标 i ,从 words 中 删除 words[i] 。其中下标 i 需要同时满足下述两个条件:
0 < i < words.length
words[i - 1] 和 words[i] 是 字母异位词 。
只要可以选出满足条件的下标,就一直执行这个操作。在执行所有操作后,返回 words 。可以证明,按任意顺序为每步操作选择下标都会得到相同的结果。
字母异位词 是由重新排列源单词的字母得到的一个新单词,所有源单词中的字母通常恰好只用一次。例如,"dacb" 是 "abdc" 的一个字母异位词。
示例 1:
输入:words = ["abba","baba","bbaa","cd","cd"]
输出:["abba","cd"]
解释:
获取结果数组的方法之一是执行下述步骤:
- 由于 words[2] = "bbaa" 和 words[1] = "baba" 是字母异位词,选择下标 2 并删除 words[2] 。
现在 words = ["abba","baba","cd","cd"] 。
- 由于 words[1] = "baba" 和 words[0] = "abba" 是字母异位词,选择下标 1 并删除 words[1] 。
现在 words = ["abba","cd","cd"] 。
- 由于 words[2] = "cd" 和 words[1] = "cd" 是字母异位词,选择下标 2 并删除 words[2] 。
现在 words = ["abba","cd"] 。
无法再执行任何操作,所以 ["abba","cd"] 是最终答案。
示例 2:输入:words = ["a","b","c","d","e"]
输出:["a","b","c","d","e"]
解释:
words 中不存在互为字母异位词的两个相邻字符串,所以无需执行任何操作。
提示:
1 <= words.length <= 100
1 <= words[i].length <= 10
words[i] 由小写英文字母组成
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/find-resultant-array-after-removing-anagrams
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
1. 题意分析
据题意,我们要将数组里后一个字符串是字母异位词的给移除掉,同源异位词是字符串长度相同且字符串包含的字母的个数也要相同,才能判断为是字母异位词。
2. 解题思路
倒序遍历数组,因为比较的是i和i-1, 同时要移除掉符合条件的i, 我们将i位置置为null。
public List<String> removeAnagrams(String[] words)
int length = words.length;
List<String> arrays = new ArrayList<>();
for (int i = length - 1; i > 0; i--)
// 判断i是否为字母异位词
if (isAnaEquals(words[i], words[i - 1]))
// 如果是,那么给i标记为null
markTarget(words, i);
for (int j = 0; j < length; j++)
if (words[j] != null)
arrays.add(words[j]);
return arrays;
从两个维度判断是否为字母异位词: 1) 长度,如果长度不等那么直接返回false。2) 从字符出现的频率来判断,频率一定要相等,我在这里没有借助map,直接将目标的word1中含word2字符的位置对应的字符给替换为index, 这样就能确保word1中的字符只有一次机会匹配到word2。
/**
* 判断word1是否是word2的同源异位词
* 1. 字符串的长度是否相同。
* 2. 判断字母出现频率是否相同。
*
* @param word1
* @param word2
* @return
*/
private boolean isAnaEquals(String word1, String word2)
if (word1.equals(word2))
return true;
if (word1.length() != word2.length())
return false;
String temp = word1;
for (int i = 0; i < word2.length(); i++)
int index = temp.indexOf(word2.charAt(i));
if (index != -1)
//包含该字符
temp = temp.substring(0, index) + index + temp.substring(index + 1);
else
return false;
return true;
3. 完整代码
package leetcode100;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* 给你一个下标从 0 开始的字符串 words ,其中 words[i] 由小写英文字符组成。
* <p>
* 在一步操作中,需要选出任一下标 i ,从 words 中 删除 words[i] 。其中下标 i 需要同时满足下述两个条件:
* <p>
* 0 < i < words.length
* words[i - 1] 和 words[i] 是 字母异位词 。
* 只要可以选出满足条件的下标,就一直执行这个操作。
* <p>
* 在执行所有操作后,返回 words 。可以证明,按任意顺序为每步操作选择下标都会得到相同的结果。
* <p>
* 字母异位词 是由重新排列源单词的字母得到的一个新单词,所有源单词中的字母通常恰好只用一次。例如,"dacb" 是 "abdc" 的一个字母异位词。
* <p>
*
* <p>
* 示例 1:
* <p>
* 输入:words = ["abba","baba","bbaa","cd","cd"]
* 输出:["abba","cd"]
* 解释:
* 获取结果数组的方法之一是执行下述步骤:
* - 由于 words[2] = "bbaa" 和 words[1] = "baba" 是字母异位词,选择下标 2 并删除 words[2] 。
* 现在 words = ["abba","baba","cd","cd"] 。
* - 由于 words[1] = "baba" 和 words[0] = "abba" 是字母异位词,选择下标 1 并删除 words[1] 。
* 现在 words = ["abba","cd","cd"] 。
* - 由于 words[2] = "cd" 和 words[1] = "cd" 是字母异位词,选择下标 2 并删除 words[2] 。
* 现在 words = ["abba","cd"] 。
* 无法再执行任何操作,所以 ["abba","cd"] 是最终答案。
* 示例 2:
* <p>
* 输入:words = ["a","b","c","d","e"]
* 输出:["a","b","c","d","e"]
* 解释:
* words 中不存在互为字母异位词的两个相邻字符串,所以无需执行任何操作。
* <p>
* 来源:力扣(LeetCode)
* 链接:https://leetcode.cn/problems/find-resultant-array-after-removing-anagrams
* 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
*/
public class RemoveAnaProblem5234
public List<String> removeAnagrams(String[] words)
int length = words.length;
List<String> arrays = new ArrayList<>();
for (int i = length - 1; i > 0; i--)
// 判断i是否为字母异位词
if (isAnaEquals(words[i], words[i - 1]))
// 如果是,那么给i标记为null
markTarget(words, i);
for (int j = 0; j < length; j++)
if (words[j] != null)
arrays.add(words[j]);
return arrays;
/**
* 判断word1是否是word2的同源异位词
* 1. 字符串的长度是否相同。
* 2. 判断字母出现频率是否相同。
*
* @param word1
* @param word2
* @return
*/
private boolean isAnaEquals(String word1, String word2)
if (word1.equals(word2))
return true;
if (word1.length() != word2.length())
return false;
String temp = word1;
for (int i = 0; i < word2.length(); i++)
int index = temp.indexOf(word2.charAt(i));
if (index != -1)
//包含该字符
temp = temp.substring(0, index) + index + temp.substring(index + 1);
else
return false;
return true;
private void markTarget(String[] words, int i)
words[i] = null;
public static void main(String[] args)
RemoveAnaProblem5234 anaProblem5234 = new RemoveAnaProblem5234();
// String[] words = new String[]"abba", "baba", "bbaa", "cd", "cd";
String[] words = new String[]"a", "b", "c", "d", "e";
// String[] words = new String[]"abbb", "aaab";
List<String> arrays = anaProblem5234.removeAnagrams(words);
System.out.println(arrays);
执行结果:
4. 时间复杂度和空间复杂度
时间复杂度最坏的情况下是每个i都和i-1都匹配上了为字母异位词,M为字符串word2的最大长度,因此为O(N*M), 字符串数组里的字符长度都不相等最快为O(N), 空间复杂度为O(N)。
二、不含特殊楼层的最大连续楼层数(中等)
Alice 管理着一家公司,并租用大楼的部分楼层作为办公空间。Alice 决定将一些楼层作为 特殊楼层 ,仅用于放松。
给你两个整数 bottom 和 top ,表示 Alice 租用了从 bottom 到 top(含 bottom 和 top 在内)的所有楼层。另给你一个整数数组 special ,其中 special[i] 表示 Alice 指定用于放松的特殊楼层。
返回不含特殊楼层的 最大 连续楼层数。
示例 1:
输入:bottom = 2, top = 9, special = [4,6]
输出:3
解释:下面列出的是不含特殊楼层的连续楼层范围:
- (2, 3) ,楼层数为 2 。
- (5, 5) ,楼层数为 1 。
- (7, 9) ,楼层数为 3 。
因此,返回最大连续楼层数 3 。
示例 2:输入:bottom = 6, top = 8, special = [7,6,8]
输出:0
解释:每层楼都被规划为特殊楼层,所以返回 0 。
提示
1 <= special.length <= 105
1 <= bottom <= special[i] <= top <= 109
special 中的所有值 互不相同
通过次数6,046提交次数11,357
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/maximum-consecutive-floors-without-special-floors
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
1. 题意分析
bottom为底层楼数,top为顶层楼数,special为包含特殊的楼层号码数组,我们需要算出每2个楼层号的间隔,最后返回最大的间隔数即可。
2. 解题思路
special数组是乱序的,因此我们可以先将special数组给排序一下,使用Arrays.sort()方法即可完成升序排列。
Arrays.sort(special);
特殊情况特殊处理, 如果special数组刚好有2个元素,那么我们直接比较(bottom,special[0]),(special[0],special[1]),(special[1],top)的差值即可。
int maxFloorNums;
Arrays.sort(special);
int maxTemp = Math.max(special[0] - bottom, top - special[special.length - 1]);
maxFloorNums = special.length == 2 ? Math.max(maxTemp, special[1] - special[0] - 1) : maxTemp;
如果 special长度大于2,那么就遍历数组,数组间的差值比较,与最大的maxFloorNums比较即可,i和i-1是特殊楼层,题意要求不含特殊楼层的连续楼层范围,也就是例如特殊楼层special数组为[4,5,6],那么在计算需要special[i] - special[i - 1]再减1。
for (int i = 1; i < special.length; i++)
int diff = special[i] - special[i - 1] - 1;
maxFloorNums = Math.max(diff, maxFloorNums);
3. 完整代码
package leetcode100;
import java.util.Arrays;
/**
* Alice 管理着一家公司,并租用大楼的部分楼层作为办公空间。Alice 决定将一些楼层作为 特殊楼层 ,仅用于放松。
* <p>
* 给你两个整数 bottom 和 top ,表示 Alice 租用了从 bottom 到 top(含 bottom 和 top 在内)的所有楼层。另给你一个整数数组 special ,其中 special[i] 表示 Alice 指定用于放松的特殊楼层。
* <p>
* 返回不含特殊楼层的 最大 连续楼层数。
* <p>
*
* <p>
* 示例 1:
* <p>
* 输入:bottom = 2, top = 9, special = [4,6]
* 输出:3
* 解释:下面列出的是不含特殊楼层的连续楼层范围:
* - (2, 3) ,楼层数为 2 。
* - (5, 5) ,楼层数为 1 。
* - (7, 9) ,楼层数为 3 。
* 因此,返回最大连续楼层数 3 。
* 示例 2:
* <p>
* 输入:bottom = 6, top = 8, special = [7,6,8]
* 输出:0
* 解释:每层楼都被规划为特殊楼层,所以返回 0 。
*
* <p>
* 提示
* <p>
* 1 <= special.length <= 105
* 1 <= bottom <= special[i] <= top <= 109
* special 中的所有值 互不相同
* <p>
* <p>
* 来源:力扣(LeetCode)
* 链接:https://leetcode.cn/problems/maximum-consecutive-floors-without-special-floors
* 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
* <p>
* 返回不喊特殊楼层的最大连续楼层数
*/
public class MaxConsecutiveProblem6064
public int maxConsecutive(int bottom, int top, int[] special)
int maxFloorNums;
Arrays.sort(special);
int maxTemp = Math.max(special[0] - bottom, top - special[special.length - 1]);
maxFloorNums = special.length == 2 ? Math.max(maxTemp, special[1] - special[0] - 1) : maxTemp;
for (int i = 1; i < special.length; i++)
int diff = special[i] - special[i - 1] - 1;
maxFloorNums = Math.max(diff, maxFloorNums);
return maxFloorNums;
public static void main(String[] args)
MaxConsecutiveProblem6064 problem6064 = new MaxConsecutiveProblem6064();
// int bottom = 2;
// int top = 9;
// int[] special = new int[]4, 6;
//
// int bottom = 6;
// int top = 8;
// int[] special = new int[]7, 6, 8;
//
// int bottom = 28;
// int top = 50;
// int[] special = new int[]35, 48;
int bottom = 1;
int top = 49;
int[] special = new int[]11, 12, 22, 49, 4, 6;
int result = problem6064.maxConsecutive(bottom, top, special);
System.out.println("result= " + result);
执行结果:
4. 时间复杂度和空间复杂度
时间复杂度为O(N),N为Special数组的长度,空间复杂度为O(1)。
以上是关于Leetcode(周赛):移除字母异位词5234,最大连续楼层数6064的主要内容,如果未能解决你的问题,请参考以下文章