Number_of_Longest_Increasing_Subsequence

题目描述:

Given an unsorted array of integers, find the number of longest increasing subsequence.
Example 1:

Input: [1,3,5,4,7]
Output: 2
Explanation: The two longest increasing subsequence are [1, 3, 4, 7] and [1, 3, 5, 7].

Example 2:

Input: [2,2,2,2,2]
Output: 5
Explanation: The length of longest continuous increasing subsequence is 1,
             and there are 5 subsequences' length is 1, so output 5.

Note: Length of the given array will be not exceed 2000 and
     the answer is guaranteed to be fit in 32-bit signed int.
(给定一个整数排序的数组,找出最长递增子序列数。
例1:
输入:[1,3,5,4,7]
输出:2
说明:两个最长的递增子序列是[1, 3, 4, 7]和[1, 3, 5, 7]。
例2:
输入:[ 2,2,2,2,2 ]
输出:5
说明:最长连续递增子序列的长度为1,
有5个序列的长度为1,所以输出5。
注意:给定数组的长度不会超过2000。
          答案被保证为int。)

思路:遍历所输入的数组,进行如下处理:遍历到元素i时,将hash表中已存在的比其小的元素进行比较,如果以较小元素j结尾的子串长度加上i大于
         原来以i结尾的子串长度,那么更新以i结尾的最大字串长度并且将以i结尾的最大字串的数量改为以j结尾的最大字串的数量,还有一种情况就
         是如果以较小元素j结尾的最大字串的长度加一等于以i结尾的最大字串长度那么就将以i结尾的最大字串数量加上以较小元素j结尾的最大字串
         的数量。但是这种处理方法会有一个漏洞就是如果遍历到的i是数组nums中的最小值,那么就不会进行如上处理,也就是不会对以i结尾的最大
         子串数量进行增加。所以针对这个漏洞我们还需每遍历到一次最小值为其进行数量上的加一(因为最小值的最大子串长度为1)。

public class Number_of_Longest_Increasing_Subsequence {
	public static int findNumberOfLIS(int[] nums) 
	{
		int result = 0;
		//存放以整数i结尾的最大子串数量
		HashMap<Integer,Integer> Count = new HashMap<Integer,Integer>();
		//存放以整数i结尾的最大子串长度
		HashMap<Integer,Integer> Length = new HashMap<Integer,Integer>();
		//最大子串长度
		int maxium = 0;
		for(int i=0;i<nums.length;i++)
		{
			//判断是否为第一次加入hash表
			boolean timeflag = false;
			//判断是否为最小的值
			boolean numflag = true;
			if(!Count.containsKey(nums[i]))
			{
				Count.put(nums[i],1);
				Length.put(nums[i],1);
			}
			else
			{
				timeflag = true;
			}
			for(int key : Count.keySet())
			{
				if(key<nums[i])
				{
					numflag = false;
					if(Length.get(key)+1>Length.get(nums[i]))
					{
						Count.put(nums[i],Count.get(key));
						Length.put(nums[i],Length.get(key)+1);
					}
					else
					{
						if(Length.get(key)+1==Length.get(nums[i]))
						{
							Count.put(nums[i],Count.get(nums[i])+Count.get(key));
						}
					}
				}
			}
			if(timeflag&&numflag)
			{
				Count.put(nums[i],Count.get(nums[i])+1);
			}			
			maxium = Math.max(Length.get(nums[i]),maxium);
		}
		for(int key : Length.keySet())
		{
			if(Length.get(key)==maxium)
			{
				result += Count.get(key);
			}
		}
		return result;        
    }
	public static void main(String[] args) {
//		int nums[] = {2,2,2,2,2};
		int nums[] = {1,3,5,4,7};
//		int nums[] = {1,2,3,1,2,3,1,2,3};
//		int nums[] = {2,3,2};
		System.out.println(findNumberOfLIS(nums));
	}
}

本题选择对以某个整数为结尾的子串进行处理这样不会保存重复数据,和 Unique_Substrings_in_Wraparound_String很类似。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值