【编程题目】求一个数组的最长递减子序列 比如{9,4,3,2,5,4,3,2}的最长递减子序列为{9,5, 4,3,2}

47.创新工场(算法):
求一个数组的最长递减子序列 比如{9,4,3,2,5,4,3,2}的最长递减子序列为{9,5,
4,3,2}

思路:动态规划

从最后一个数字开始,计算以当前数字其实的序列的最长递减子序列。 每次找最长子序列,都扫描它之前求得的子序列中最长,且第一个数字比当前数字小的。

如: 第一个数字 2, 最大长度 1, 下一个数字是 第 7 个

第二个数字 3,  最大长度 2, 下一个数字是 第 7 个

第三个数字 4,  最大长度 3, 下一个数字是 第 6 个

第四个数字 5,  最大长度 4, 下一个数字是 第 5 个

第五个数字 2,  最大长度 1, 下一个数字是 第 3 个

第六个数字 3,  最大长度 2, 下一个数字是 第 3 个

第七个数字 4,  最大长度 3, 下一个数字是 第 2 个

第八个数字 9,  最大长度 5, 下一个数字是 第 4 个

这样就可以找到最大长度,并根据存储的下一个数字找到最长递减序列。

/*
47.创新工场(算法):
求一个数组的最长递减子序列  比如{9,4,3,2,5,4,3,2}的最长递减子序列为{9,5,
4,3,2}
*/

#include <stdio.h>
#include <stdlib.h>

int maxLength(int * a, int len)
{
    int * pos = (int *)malloc(2 * len * sizeof(int));

    //找到以每一个元素起始的最长递减子序列
    pos[2 * (len - 1)] = 1; //以最后一个数字为首的最长递减子序列长度
    pos[2 * len - 1] = len - 1; //最后一个数的下一个数字
    for (int i = len - 2; i >= 0; i--)
    {
        int maxlen = 0;
        int nextpos = i;
        for (int j = i + 1; j < len; j++)
        {
            if (a[j] < a[i])
            {
                if (pos[2 * j] > maxlen)
                {
                    maxlen = pos[2 *j];
                    nextpos = j;
                }
            }
        }
        pos[2 * i] = maxlen + 1; //以a[i]为首的最长递减子序列长度
        pos[2 * i + 1] = nextpos; //a[i]的下一个数字
    }

    //找到最长的递减序列
    int maxstart = 0;
    int max = 0;
    for (int i = 0; i < len; i++)
    {
        if (pos[2 * i] > max)
        {
            max = pos[2 * i];
            maxstart = i;
        }
    }

    //打印最长递减子序列
    printf("最长递减子序列为:");

    int next = maxstart;
    do
    {
        printf("%d ", a[next]);
        next = pos[2 * next + 1];
    }while(next != pos[2 * next + 1]);
    printf("%d\n", a[next]);

    free(pos);
    return max; //返回最大长度
}

int main()
{
    int a[8] = {9,4,3,2,5,4,3,2};
    int len = maxLength(a,8);
    return 0;
}

发现我又有一个地方傻×了,其实可以不用存下一个数字的位置的,直接查找最大长度少一的数字并打印就可以了。

如下:http://blog.csdn.net/wumuzi520/article/details/7378306

#include <iostream>
#include <cstring>
using namespace std;

int Fun(int aIn[],int pTable[],int nLen)
{
    int nMaxLen = 0;
    for(int i = nLen-1; i >= 0; --i) {
        int nMax = 0;
        for(int j = i+1; j < nLen; ++j) {
            if(aIn[j] < aIn[i]) {
                nMax = nMax < pTable[j] ? pTable[j] : nMax;
            }
        }
        pTable[i] = 1+nMax;
        nMaxLen = nMaxLen<pTable[i] ? pTable[i] : nMaxLen;
    }

    return nMaxLen;
}

void PrintMaxSubsequence(int aIn[], int pTable[], int nMaxLen, int nLen)   //!!!!!!!!!!
{
    for(int i = 0,j=0; i < nLen; ++i) {
        if(pTable[i] == nMaxLen){
            cout << aIn[i] << " ";
            nMaxLen--;
        }
    }
    cout << endl;
}

【编程题目】求一个数组的最长递减子序列 比如{9,4,3,2,5,4,3,2}的最长递减子序列为{9,5, 4,3,2}

时间: 2024-09-30 19:17:14

【编程题目】求一个数组的最长递减子序列 比如{9,4,3,2,5,4,3,2}的最长递减子序列为{9,5, 4,3,2}的相关文章

【编程题目】一个数组是由一个递减数列左移若干位形成的,在这种数组中查找某一个数。☆

48.微软(运算):一个数组是由一个递减数列左移若干位形成的,比如{4,3,2,1,6,5}是由{6,5,4,3,2,1}左移两位形成的,在这种数组中查找某一个数. 我的思路: 非常麻烦:先是用二分法找最大的数的位置,再定位要找的数在哪个递减区间里,最后用普通的二分查找法找到.代码如下: /* 48.微软(运算): 一个数组是由一个递减数列左移若干位形成的,比如{4,3,2,1,6,5} 是由{6,5,4,3,2,1}左移两位形成的,在这种数组中查找某一个数. */ #include <stdi

算法 - 求一个数组的最长递减子序列(C++)

//**************************************************************************************************** // // 求一个数组的最长递减子序列 - C++ - by Chimomo // // 题目: 求一个数组的最长递减子序列,比方{8, 14, 6, 2, 8, 14, 3, 2, 7, 4, 7, 2, 8, 101, 23, 6, 1, 2, 1, 1}的最长递减子序列为{14.8,3.

【编程题目】把数组排成最小的数

68.把数组排成最小的数(数组.算法).题目:输入一个正整数数组,将它们连接起来排成一个数,输出能排出的所有数字中最小的一个.例如输入数组{32, 321},则输出这两个能排成的最小数字 32132.请给出解决问题的算法,并证明该算法. 思路:首先,肯定要考虑溢出问题.开始想用字符串,后来改为了用list.思路是先把第一个数字放入list,然后依次把后面的数字插入到合适的位置. 关键问题就是如何判断两个数字哪一个在前面. ①对于 353 .412这样的情况,肯定是第一个数字小的在前面 ②遇到数字

【编程题目】调整数组顺序使奇数位于偶数前面

54.调整数组顺序使奇数位于偶数前面(数组).题目:输入一个整数数组,调整数组中数字的顺序,使得所有奇数位于数组的前半部分,所有偶数位于数组的后半部分.要求时间复杂度为 O(n). 小题,秒灭. /* 54.调整数组顺序使奇数位于偶数前面(数组). 题目:输入一个整数数组,调整数组中数字的顺序,使得所有奇数位于数组的前半部分, 所有偶数位于数组的后半部分.要求时间复杂度为 O(n). */ #include <stdio.h> #include <algorithm> using

软件工程结对开发之求一个数组中连续最大子数组之和

一.团队成员: 檀威,陈志利 二.项目名: 求一个数组中连续最大子数组之和 三.我们的设计思路: 设sum[i]为以第i个元素结尾且和最大的连续子数组.对于元素i,所有以它前面的元素结尾的子数组的长度都已经求得,那么以第i个元素结尾且它们之和最大的连续子数组要么是以第i-1个元素结尾且它们之和最大的连续子数组加上这个元素,要么是只包含第i个元素,即sum[i] = max(sum[i-1] + arr[i], arr[i]).可以通过判断sum[i-1] + arr[i]是否大于arr[i]来做

【编程题目】旋转数组中的最小元素☆

69.旋转数组中的最小元素(数组.算法).题目:把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转.输入一个排好序的数组的一个旋转,输出旋转数组的最小元素.例如数组{3, 4, 5, 1, 2}为{1, 2, 3, 4, 5}的一个旋转,该数组的最小值为 1. 我就用了最简单的方法.而且开始还没考虑1, 0, 1 ,1这样的情况 /* 69.旋转数组中的最小元素(数组.算法). 题目:把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转.输入一个 排好序的数组的一个旋转

求一个数组中只出现一次的数字

/* 求一个数组中只出现一次的数字(注:只针对数组中有两个数不同,且其他数字两两相同) 题目:一个整型数组里除了两个数字出现一次外,其他的数字都出现了两次:求出现一次的数字: 如:数组a[]={2,4,3,6,3,2,5,5};执行程序后应输出4和6:因为4,6只在该数组中出现了一次 思路:两个数字相同其异或结果一定为0,先异或->再分组-->再对每个子序列异或 算法: 1. 先对数组的每一个元素进行异或操作,求结果(本质就是对那两个不同的数的异或,即4^6=0010) 2.根据异或的操作结果

java实现求一个数组里最大值和最小值之前缺省的数的算法

问题描述: 求一个数组里最大值和最小值之间缺省的数,例如 int arrDemo = {1, 3, 7};  那么就要输出最小值1和最大值7之间缺少的数字2,4,5,6 代码如下,有更好的思路欢迎大家在评论区留言讨论 1 package test; 2 3 public class Test { 4 5 static int[] array = { 6 -10,0,3,3,9 7 }; 8 9 private static void printEmptyItems(int[] array) {

《团队开发一(求一个数组的连续的子数组之和的最大值)》

(1)设计思想:一般的,求一个数组的最大子数组之和即是按数组顺序依次让前几个数的和与下一个数进行比较,设一变量来装每次比较后的较大的数,依此进行到数组终端:但是考虑到求的是连续的子数组,则应该想到除了在按顺序上的连续外,还得考虑到末端与首端的连续,所以按数组顺序依次求解得到的未必就是连续的最大的子数组之和,故此必须在此种情况下也求解出最大子数组之和,方法即是同时从数组的两端依次进行求出各自的最大子数组之和,然后在相遇前求和后与之前所求的最大子数组之和依次相比较,取它们中最大的一个作为连续的最大子