Leetcode(周赛):移除字母异位词5234,最大连续楼层数6064

Posted Dream_it_possible!

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Leetcode(周赛):移除字母异位词5234,最大连续楼层数6064相关的知识,希望对你有一定的参考价值。

目录

一、字母异位词(简单)

1. 题意分析

2. 解题思路

3. 完整代码

4. 时间复杂度和空间复杂度

二、不含特殊楼层的最大连续楼层数(中等)

1. 题意分析

2. 解题思路

3. 完整代码

4. 时间复杂度和空间复杂度


一、字母异位词(简单)

给你一个下标从 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的主要内容,如果未能解决你的问题,请参考以下文章

Leetcode(周赛):移除字母异位词5234,最大连续楼层数6064

LeetCode-242-有效的字母异位词

LeetCode 242. 有效的字母异位词

LeetCode 0049.字母异位词分组

leetcode-49字母异位词分组

leetCode242 有效的字母异位词