leetcode 594. Longest Harmonious Subsequence

257 篇文章 17 订阅

We define a harmonious array is an array where the difference between its maximum value and its minimum value is exactly 1.

Now, given an integer array, you need to find the length of its longest harmonious subsequence among all its possible subsequences.

Example 1:

Input: [1,3,2,2,5,2,3,7]
Output: 5
Explanation: The longest harmonious subsequence is [3,2,2,2,3].

Note: The length of the input array will not exceed 20,000.

需要注意的是,这道题的意思是:最大值与最小值的差 正好 是1,而不是小于等于1。

比如测试用例:结果就应该是0。

下面是我的解法。

public int findLHS(int[] nums) {
	if(nums.length<=1){
		return 0;
	}		
	//map中存储某个数出现了多少次
	HashMap<Integer, Integer> preCount=new HashMap<Integer, Integer>();
	int maxLength=0;
	for(int i=0;i<nums.length;i++){
		int number=nums[i];
		int numberCount=preCount.getOrDefault(number, 0);
		//拿到number-1和number+1迄今为止出现的次数
		int numberMinus1Count=preCount.getOrDefault(number-1, 0);
		int numberPlus1Count=preCount.getOrDefault(number+1, 0);
		if(numberMinus1Count!=0 || numberPlus1Count!=0){
			int nowMax=1+numberCount+Math.max(numberMinus1Count, numberPlus1Count);
			if(nowMax>maxLength){
				maxLength=nowMax;
			}
		}		
		preCount.put(number, numberCount+1);
	}
	return maxLength;	
}
大神也用hashmap,不过方法有点不同。

思路是得到每个数字的出现个数,然后再检查每个数字的+1元素的个数。

public int findLHS(int[] nums) {
    Map<Long, Integer> map = new HashMap<>();
    for (long num : nums) {
        map.put(num, map.getOrDefault(num, 0) + 1);
    }
    int result = 0;
    for (long key : map.keySet()) {
        if (map.containsKey(key + 1)) {
            result = Math.max(result, map.get(key + 1) + map.get(key));
        }
    }
    return result;
}
使用long而不是int的原因是防止出现测试用例是:new int[]{ -2147483648 , 2147483647} 的情况,因为2147483647 + 1 = -2147483648,不是我们希望的结果。
并且,不需要同时检查   key+1  和  key-1  , 因为假设在一个有效答案中有 key 和 key-1 , 那么在以 key-1 作为 key 时就能够得到这个答案。

这道题有solutions:https://leetcode.com/problems/longest-harmonious-subsequence/solution/。solutions中的解法我基本上面两个都提到了。

Approach #3 Using Sorting [Accepted]

Algorithm

Since we are concerned only with the count of elements which are at a difference of 1, we can use sorting to our advantage. If we sort the given numsnums array, the related elements will get arranged close to each other. Thus, we can traverse over the sorted array, and find the count of similar elements and elements one larger than the current ones, which occur consecutively(all the similar elements will be lying consecutively now). Initially, this value is stored in prev\_countprev_countvariable. Then, if we encounter an element which is just 1 larger than the last elements, we count the occurences of such elements as well. This value is stored in countcount variable.

Thus, now for the harmonic subsequence comprised of only these two elements is a subsequence of length count + prev\_countcount+prev_count. This result is stored in resresfor each subsequence found. When we move forward to considering the next set of similar consecutive elements, we need to update the prev\_countprev_count with the countcount's value, since now countcount will act as the count of the elements 1 lesser than the next elements encountered. The value of resres is always updated to be the larger of previous resres and the current count + prev\_countcount+prev_count value.

When we are done traversing over the whole array, the value of resres gives us the required result.

Java

public class Solution {
    public int findLHS(int[] nums) {
        Arrays.sort(nums);
        int prev_count = 1, res = 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++;
                }
                res = Math.max(res, count + prev_count);
                prev_count = count;
            } else {
                while (i < nums.length - 1 && nums[i] == nums[i + 1]) {
                    count++;
                    i++;
                }
                prev_count = count;
            }
        }
        return res;
    }
}

Complexity Analysis

  • Time complexity : O(nlogn)O(nlogn). Sorting takes O(nlogn)O(nlogn) time.

  • Space complexity : O(logn)O(logn)lognlogn space is required by sorting in average case.


Approach #4 Using HashMap[Accepted]:

Algorithm

In this approach, we make use of a hashmap mapmap which stores the number of times an element occurs in the array along with the element's value in the form (num: count\_num)(num:count_num), where numnum refers to an element in the array and count\_numcount_num refers to the number of times this numnum occurs in the numsnums array. We traverse over the numsnums array and fill this mapmap once.

After this, we traverse over the keys of the mapmap created. For every key of the mapmap considered, say keykey, we find out if the map contains the key + 1key+1. Such an element is found, since only such elements can be counted for the harmonic subsequence if keykey is considered as one of the element of the harmonic subsequence. We need not care about key - 1key1, because if keykey is present in the harmonic subsequence, at one time either key + 1key+1 or key - 1key1 only could be included in the harmonic subsequence. The case of key - 1key1 being in the harmonic subsequence will automatically be considered, when key - 1key1 is encountered as the current key.

Now, whenver we find that key + 1key+1 exists in the keys of mapmap, we determine the count of the current harmonic subsequence as count_{key} + count_{key+1}countkey+countkey+1, where count_icounti refers to the value corresponding to the key ii in mapmap, which reprents the number of times ii occurs in the array numsnums.

Look at the animation below for a pictorial view of the process:

Java

public class Solution {
    public int findLHS(int[] nums) {
        HashMap < Integer, Integer > map = new HashMap < > ();
        int res = 0;
        for (int num: nums) {
            map.put(num, map.getOrDefault(num, 0) + 1);
        }
        for (int key: map.keySet()) {
            if (map.containsKey(key + 1))
                res = Math.max(res, map.get(key) + map.get(key + 1));
        }
        return res;
    }
}

Complexity Analysis

  • Time complexity : O(n)O(n). One loop is required to fill mapmap and one for traversing the mapmap.

  • Space complexity : O(n)O(n). In worst case map size grows upto size nn.


Approach #5 In single loop [Accepted]:

Algorithm

Instead of filling the mapmap first and then traversing over the mapmap to determine the lengths of the harmonic subsequences encountered, we can traverse over the numsnums array, and while doing the traversals, we can determine the lengths of the harmonic subsequences possible till the current index of the numsnums array.

The method of finding the length of harmonic subsequence remains the same as the last approach. But, this time, we need to consider the existence of both key + 1key+1 and key - 1key1 exclusively and determine the counts corresponding to both the cases. This is needed now because it could be possible that keykey has already been added to the mapmap and later on key - 1key1 is encountered. In this case, if we consider the presence of key + 1key+1 only, we'll go in the wrong direction.

Thus, we consider the countcounts corresponding to both the cases separately for every keykey and determine the maximum out of them. Thus, now the same task can be done only in a single traveral of the numsnums array.

See the animation below for understanding the process:

Java

public class Solution {
    public int findLHS(int[] nums) {
        HashMap < Integer, Integer > map = new HashMap < > ();
        int res = 0;
        for (int num: nums) {
            map.put(num, map.getOrDefault(num, 0) + 1);
            if (map.containsKey(num + 1))
                res = Math.max(res, map.get(num) + map.get(num + 1));
            if (map.containsKey(num - 1))
                res = Math.max(res, map.get(num) + map.get(num - 1));
        }
        return res;
    }
}

Complexity Analysis

  • Time complexity : O(n)O(n). Only one loop is there.

  • Space complexity : O(n)O(n)mapmap size grows upto size nn.


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值