最长递增子连串,最和谐的子种类

和谐数组是指一个数组里成分的最大值和最小值之间的异样正好是1。

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

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

交付长度为N的数组,找出这一个数组的最长递增子序列。(递增子体系是指,子种类的因素是比比皆是的)

于今,给定二个平头数组,你需求在富有只怕的子体系中找到最长的和谐子序列的长短。

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

最长递增子连串,最和谐的子种类。Now, given an integer array, you need to find the length of its longest
harmonious subsequence among all its
possible subsequences.

譬如说:5
1 6 8 2 4 5 10,最长递增子种类是1 2 4 5 10。

示例 1:

Example 1:

Example 1:

 

输入: [1,3,2,2,5,2,3,7]
输出: 5
原因: 最长的和谐数组是:[3,2,2,2,3].
Input: [1,3,2,2,5,2,3,7]
Output: 5
Explanation: The longest harmonious subsequence is [3,2,2,2,3].
Input: [1,3,2,2,5,2,3,7]
Output: 5
Explanation: The longest harmonious subsequence is [3,2,2,2,3].

Input

说明: 输入的数COO度最大不超过20,000.

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

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

第1行:1个数N,N为序列的长度(2 <= N <= 50000)
第2 - N + 1行:每行1个数,对应序列的元素(-10^9 <= S[i] <= 10^9)

 

至于和谐子序列就是体系中数组的最大一点都不大差值均为1。由于此地只是让我们求长度,并不须要重回具体的子连串。所以大家能够对数组进行排序,那么实际上大家只要找出来相差为1的四个数的一起出现个数就是叁个和谐子系列的长短了。通晓了那一点,大家就可以建立一个数字和其现出次数之间的投射,利用map的电动排序的本性,那么大家遍历map的时候就是从小往大起来遍历,大家从第③个映射对起来遍历,每便跟其前方的炫耀对比较,即便两者的数字刚好差1,那么就把二个数字的产出的次数相加并创新结果res即可,就是golang的完结格局,参考代码

有关和谐子系列就是系列中数组的最大不大差值均为1。由于此处只是让大家求长度,并不需求重回具体的子系列。所以大家可以对数组进行排序,那么实际上大家只要找出来相差为1的多少个数的一共出现个数就是3个和谐子系列的尺寸了。了解了那或多或少,我们就可以建立多个数字和其冒出次数之间的映照,利用map的机关排序的特征,那么我们遍历map的时候即使从小往大起来遍历,大家从第四个映射对开端遍历,每便跟其眼下的投射相比较,如若两岸的数字刚好差1,那么就把1个数字的面世的次数相加并立异结果res即可,就是golang的贯彻形式,参考代码

 

from collections import Counter
class Solution:
    def findLHS(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        new_nums=Counter(nums)
        tmp = 0
        lastkey,lastvalue=None,None
        for key,value in sorted(new_nums.items()):
            if lastkey is not None and lastkey +1 ==key:
                tmp = max(tmp,value+lastvalue)
            lastkey,lastvalue=key,value
        return tmp
func findLHS(nums []int) int {

    //给输入的数组排序

    numSlice := sort.IntSlice(nums)

    sort.Sort(numSlice)

    //map是无序的所以用slice来记住顺序的数字(已经去掉重复)

    var keySlice []int = make([]int, 0)

    var dic = make(map[int]int)

    for i := 0; i < len(numSlice); i++ {

        if _, ok := dic[numSlice[i]]; ok {

            dic[numSlice[i]] += 1

        } else {

            dic[numSlice[i]] = 1

            keySlice = append(keySlice, numSlice[i])

        }

    }

    var maxLength int

    for k, v := range keySlice {

        if k <= len(numSlice)-1 {

            if _, ok := dic[v+1]; ok {

                if maxLength < dic[v]+dic[v+1] {

                    maxLength = dic[v] + dic[v+1]

                }

            }

        }

    }

    return maxLength

}
func findLHS(nums []int) int {

    //给输入的数组排序

    numSlice := sort.IntSlice(nums)

    sort.Sort(numSlice)

    //map是无序的所以用slice来记住顺序的数字(已经去掉重复)

    var keySlice []int = make([]int, 0)

    var dic = make(map[int]int)

    for i := 0; i < len(numSlice); i++ {

        if _, ok := dic[numSlice[i]]; ok {

            dic[numSlice[i]] += 1

        } else {

            dic[numSlice[i]] = 1

            keySlice = append(keySlice, numSlice[i])

        }

    }

    var maxLength int

    for k, v := range keySlice {

        if k <= len(numSlice)-1 {

            if _, ok := dic[v+1]; ok {

                if maxLength < dic[v]+dic[v+1] {

                    maxLength = dic[v] + dic[v+1]

                }

            }

        }

    }

    return maxLength

}

Output

 

  

  

输出最长递增子序列的长度。

 

Input示例

8
5
1
6
8
2
4
5
10

 

Output示例

5

 

//第2种做法,放入二个数然后更新

#include <iostream>
#include <stdio.h>
#include <string.h>
using namespace std;
long long a[100000],b[100000];
int main(){
    int n;
    while(cin>>n){
        memset(a,1000000009,sizeof(a));
        memset(b,1000000009,sizeof(b));
        int i,j;
        for(i=0;i<n;i++)
            cin>>a[i];
        int x=0;
        for(i=0;i<n;i++){
            for(j=0;j<n;j++){
                if(a[i]<b[j]){  //每次放入一个数,找到适当的位置更新
                    b[j]=a[i];
                    if(j>x) x=j;
                    break;   //因为一个数只用一次更新,所以循环结束
                }
            }
        }
        cout<<x+1<<endl;
    }
    return 0;
}


//第二种runtime  ……额 ……┭┮﹏┭┮……等我不这么菜了,再改

创制三个协助数组c[n],c[i]存储的是子体系长度为i的种类最终一值即
子体系长度为i有多少个,但是须求末了一个值最小,
比如
1, 4,7,3,8,2,1
1,4
1,3
1,2
1,1
在此此前今后遍历数组a[n],处理a[i-1]时,旁观c数组,每一个a数组中的值和
c数组中的值进行相比较,找到确切的职分插入(若插入到c数组的末尾,那么
所求最长上升子连串长度+1,恩,,你应有隐隐感受到了怎么着了吗,不错呢c数组的
长度就是最后大家所须求滴,撤回来),否则就替换掉c数组原来地点上的值
那有助于大家通过a数组计算b数组(b[i]中保存的是以a[i]为结尾3个因素的
最长单调递增子体系)
若a[i]<a[j],就b[j]澳门葡京备用网址,赋值b[i] c中草药保存a[i]

鉴于c数组下标代表子体系长度,c数组中的值也是按递增系列排序,所以很合乎二分

 

#include <iostream>
using namespace std;

int find(int *a,int len,int n){   //二分find
    int l=0,r=len,mid=(l+r)>>1;
    while(l<=r){
        if(n>a[mid]) l=mid+1;
        else if(n<a[mid]) r=mid-1;
        else return mid;
        mid=(l+r)>>1;
    }
}
void init(int *a,int n){
    for(int i=0;i<=n;i++)
        a[i]=1000;
}
int main(){
    int maxn,i,j,n,a[100],b[100],c[100];
    while(cin>>n){
        init(c,n+1);
        for(i=0;i<n;i++)
            cin>>a[i];
        c[0]=-1;        //天然最小值
        c[1]=a[0];     //initialization
        b[0]=1;       //b[i]表示以a[i]结尾的最长单调递增子序列
        for(i=1;i<n;i++){  //复杂度是N
            j=find(c,n+1,a[i]);    //复杂度logN的
            c[j]=a[i];
            b[i]=j;
        }
        for(maxn=i=0;i<n;i++)  //遍历一遍找到最大值
            if(b[i]>maxn)
            maxn=b[i];
        cout<<maxn<<endl;
    }
    return 0;
}

  

  

相关文章

发表评论

电子邮件地址不会被公开。 必填项已用*标注

*
*
Website