LeetCode算法题-Longest Harmonious Subsequence(Java实现)

这是悦乐书的第270次更新,第284篇原创

01 看题和准备

今天介绍的是LeetCode算法题中Easy级别的第136题(顺位题号是594)。我们定义一个和谐数组是一个数组,其最大值和最小值之间的差值恰好为1。给定一个整数数组,在其所有可能的子序列中找到其最长的和谐子序列的长度。例如:

输入:[1,3,2,2,5,2,3,7]
输出:5
说明:最长的和谐子序列是[3,2,2,2,3]。

注意:输入数组的长度不会超过20,000。

本次解题使用的开发工具是eclipse,jdk使用的版本是1.8,环境是win7 64位系统,使用Java语言编写和测试。

02 第一种解法

直接使用两层for循环,依次遍历元素,如果当前元素在数组中不存在与之值相差为1的数,标志flag就为false,那么此元素就不参与计算,反之存在,就把自己出现的次数与其值相差为1的元素的出现次数加起来,并且flag改为true,取最大值即可。

public int findLHS(int[] nums) {
    if (nums == null || nums.length < 2) {
        return 0;
    }
    int result = 0;
    for(int i=0; i<nums.length; i++){
        boolean flag = false;
        int count = 0;
        for (int j=0; j<nums.length; j++) {
            if (nums[i] == nums[j]) {
                count++;
            } else if (nums[i] == nums[j]-1) {
                flag = true;
                count++;
            }
        }
        if (flag) {
            result = Math.max(result, count);
        }
    }
    return result;
}

03 第二种解法

先对数组进行升序排序,借助Arrays.sort方法来实现,然后遍历数组的元素。

排完序后,可以先将两种特殊情况直接返回结果,如果排序后的数组第一个元素与最后一个元素值相等,直接返回0;如果数组第一个元素与最后一个元素值相差1,返回数组长度。

如果当前元素连续出现,我们需要先将其出现次数记录下来,使用变量preCount来存值,在遇到与其值相差为1的元素时,再将与其值相差为1的元素的出现次数记录下来,加上preCount的值,就表示此和谐数组的长度,再去与所有可能的和谐数组长度做比较取最大值。

如果当前元素不是连续出现,那么preCount的值就为1,表示当前元素只出现了一次,然后判断下一个元素是否与其值相差1,如果下一个元素符合条件,就找到该元素出现的次数,加上preCount的值,两次数之和与最大值取较大者。

public int findLHS2(int[] nums) {
    if (nums == null || nums.length < 2) {
        return 0;
    }
    Arrays.sort(nums);
    if (nums[0] == nums[nums.length-1]) {
        return 0;
    }
    if (nums[0] == nums[nums.length-1]-1) {
        return nums.length;
    }
    int preCount = 1, result = 0;
    for (int i = 0; i < nums.length; i++) {
        int count = 1;
        if (i > 0 && nums[i] - nums[i - 1] == 1) {
            while (i < nums.length - 1 && nums[i] == nums[i + 1]) {
                count++;
                i++;
            }
            result = Math.max(result, count + preCount);
            preCount = count;
        } else {
            while (i < nums.length - 1 && nums[i] == nums[i + 1]) {
                count++;
                i++;
            }
            preCount = count;
        }
    }
    return result;
}

04 第三种解法

使用HashMap,以数组中的每个元素为key,其出现次数为value,然后遍历map中的每个key,如果map中含有比当前key值大1的key,那么将当前key所对应的value与当前key加1后所对应的value相加,就表示一组和谐数组,在所有可能的和谐数组中找出最大值即可。为了避免溢出,HashMap中的key的类型取Long。

public int findLHS3(int[] nums) {
    if (nums == null || nums.length < 2) {
        return 0;
    }
    int result = 0;
    Map<Long, Integer> map = new HashMap<Long, Integer>();
    for (long n : nums) {
        map.put(n, map.getOrDefault(n, 0)+1);
    }
    for (long key : map.keySet()) {
        if (map.containsKey(key+1)) {
            result = Math.max(result, map.get(key)+map.get(key+1));
        }
    }
    return result;
}

05 第四种解法

我们可以将上面的解法再精简下,变成一个循环。有一点需要注意,与当前元素能够组成和谐数组的数,可能比自己大1,也可能比自己小1,并且可能还在当前元素的后面出现,所以需要将两种情况都考虑进去。

public int findLHS4(int[] nums) {
    if (nums == null || nums.length < 2) {
        return 0;
    }
    HashMap<Long, Integer> map = new HashMap<Long, Integer>();
    int result = 0;
    for (long n: nums) {
        map.put(n, map.getOrDefault(n, 0)+1);
        if (map.containsKey(n+1)) {
            result = Math.max(result, map.get(n) + map.get(n+1));
        }
        if (map.containsKey(n-1)) {
            result = Math.max(result, map.get(n) + map.get(n-1));
        }
    }
    return result;
}

06 小结

算法专题目前已日更超过四个月,算法题文章137+篇,公众号对话框回复【数据结构与算法】、【算法】、【数据结构】中的任一关键词,获取系列文章合集。

以上就是全部内容,如果大家有什么好的解法思路、建议或者其他问题,可以下方留言交流,点赞、留言、转发就是对我最大的回报和支持!

原文地址:https://www.cnblogs.com/xiaochuan94/p/10493675.html

时间: 2024-08-28 18:29:18

LeetCode算法题-Longest Harmonious Subsequence(Java实现)的相关文章

LeetCode算法题-Longest Uncommon Subsequence I(Java实现)

这是悦乐书的第252次更新,第265篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第119题(顺位题号是521).给定一组两个字符串,您需要找到这组两个字符串中最长的不同子序列.最长的不同子序列被定义为这些字符串之一的最长子序列,并且此子序列不应该是其他字符串的任何子序列. 子序列是可以通过删除一些字符而不改变其余元素的顺序从一个序列导出的序列.任何字符串都是其自身的子序列,空字符串是任何字符串的子序列.输入将是两个字符串,输出需要是最长的不同子序列的长度.如果最长

LeetCode算法题-Single Number(Java实现)

这是悦乐书的第175次更新,第177篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第34题(顺位题号是136).给定一个非空的整数数组,除了一个元素外,每个元素都会出现两次. 找到那个只出现了一次的元素.例如: 输入:[2,2,1] 输出:1 输入:[4,1,2,1,2] 输出:4 本次解题使用的开发工具是eclipse,jdk使用的版本是1.8,环境是win7 64位系统,使用Java语言编写和测试. 02 第一种解法 因为已经限定传入的数组不为空,所以此题不需要

LeetCode算法题-Min Stack(Java实现)

这是悦乐书的第177次更新,第179篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第36题(顺位题号是155).设计一个支持push,pop,top和在恒定时间内检索最小元素的堆栈. push(x) - 将元素x推入堆栈. pop() - 删除堆栈顶部的元素. top() - 获取顶部元素. getMin() - 检索堆栈中的最小元素. 例如: MinStack minStack = new MinStack(); minStack.push(-2); minSta

LeetCode算法题-Reverse Bits(Java实现)

这是悦乐书的第185次更新,第187篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第44题(顺位题号是190).给定32位无符号整数,求它的反转位.例如: 输入:43261596 输出:964176192 说明:43261596以二进制表示为00000010100101000001111010011100, 964176192以二进制表示为00111001011110000010100101000000. 本次解题使用的开发工具是eclipse,jdk使用的版本是1

LeetCode算法题-Move Zeroes(Java实现-三种解法)

这是悦乐书的第201次更新,第211篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第67题(顺位题号是283).给定一个数组nums,写一个函数将所有0移动到它的末尾,同时保持非零元素的相对顺序.例如: 输入:[0,1,0,3,12] 输出:[1,3,12,0,0] 注意: 您必须在不制作数组副本的情况下就地执行此操作. 最小化操作总数. 本次解题使用的开发工具是eclipse,jdk使用的版本是1.8,环境是win7 64位系统,使用Java语言编写和测试. 02

LeetCode算法题-Word Pattern(Java实现)

这是悦乐书的第202次更新,第212篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第68题(顺位题号是290).给定一个模式和一个字符串str,找到str是否完全匹配该模式.完全匹配是指在模式中的字母和str中的非空单词之间存在一一对应的关系.例如: 输入:pattern ="abba",str ="dog cat cat dog" 输出:true 输入:pattern ="abba",str ="dog

LeetCode算法题-Binary Watch(Java实现)

这是悦乐书的第216次更新,第229篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第84题(顺位题号是401).二进制手表顶部有4个LED,代表小时(0-11),底部的6个LED代表分钟(0-59).每个LED代表一个零或一个,右侧的最低有效位.给定非负整数n表示当前打开的LED数量,返回手表可能代表的所有可能时间.例如: 输入:n = 1 输出:["1:00","2:00","4:00","8:00&qu

LeetCode算法题-Add Strings(Java实现)

这是悦乐书的第223次更新,第236篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第90题(顺位题号是415).给定两个非负整数num1和num2表示为字符串,返回num1和num2的总和. 注意: num1和num2的长度均<5100. num1和num2都只包含数字0-9. num1和num2都不包含任何前导零. 您不能使用任何内置BigInteger库或直接将输入转换为整数. 本次解题使用的开发工具是eclipse,jdk使用的版本是1.8,环境是win7 6

LeetCode算法题-Arranging Coins(Java实现)

这是悦乐书的第229次更新,第241篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第96题(顺位题号是441).您想要以楼梯形状形成总共n个硬币,其中每个第k行必须具有恰好k个硬币.给定n,找到可以形成的完整楼梯行的总数.n是一个非负整数,适合32位有符号整数的范围.例如: n = 5 硬币可以形成以下行: ¤ ¤¤ ¤¤ 因为第3行不完整,我们返回2. n = 8 硬币可以形成以下行: ¤ ¤¤ ¤¤¤ ¤¤ 因为第4行不完整,我们返回3. 本次解题使用的开发工具