Arrays 排序数组所需的最小操作数

Arrays 排序数组所需的最小操作数,arrays,algorithm,sorting,greedy,Arrays,Algorithm,Sorting,Greedy,我正在练习解决一个来自Codeforces的问题。它是通过将数组的元素移动到数组的开头或结尾来对数组进行排序。起初我认为它是最长的递增子序列,但在某些情况下不起作用。例如,如果输入为4,1,2,5,3,则LIS为3,但问题的答案是将4移动到数组的末尾,然后将5移动到数组的末尾,从而得到2。我还尝试了示例1,6,4,5,9,8,7,3,2,在这个LIS中是1,4,5,9,但问题的答案是1和2之间的7个移动。我知道我应该使用贪婪的方法,但我不能完全理解。有人能帮我吗?我们可以看到,要对数组进行排序,

我正在练习解决一个来自Codeforces的问题。它是通过将数组的元素移动到数组的开头或结尾来对数组进行排序。起初我认为它是最长的递增子序列,但在某些情况下不起作用。例如,如果输入为4,1,2,5,3,则LIS为3,但问题的答案是将4移动到数组的末尾,然后将5移动到数组的末尾,从而得到2。我还尝试了示例1,6,4,5,9,8,7,3,2,在这个LIS中是1,4,5,9,但问题的答案是1和2之间的7个移动。我知道我应该使用贪婪的方法,但我不能完全理解。有人能帮我吗?

我们可以看到,要对数组进行排序,每个元素最多只需移动一个

所以,为了最小化移动的数量,我们需要找到未移动元素的最大数量。这些元素是最长的连续序列,它是
(a0,a1,…an)
,其中
a(i+1)=ai+1

比如说,

(4,1,2,5,3),最长连续序列为(1,2,3)

(5,2,1,3,4),最长连续序列为(2,3,4)

所以我们有我们的代码:

int[]longest = new int[n + 1];
int result = 0;
for(int i = 0; i < n; i++){
    longest[data[i]] = longest[data[i] - 1] + 1;
    result = max (longest[data[i]] , result);
}

print "Minimum number of move is " + (n - result)
int[]最长=新的int[n+1];
int结果=0;
对于(int i=0;i
说明:

在代码中,我使用了一个数组
longest
,该数组的索引
ith
存储最长的连续序列,该序列以
值I
结束

因此,我们可以看到
longest[i]=longest[i-1]+1


最长连续序列的结果是存储在
longest
数组中的最大值。

我们可以看到,要对数组进行排序,每个元素最多只需移动

所以,为了最小化移动的数量,我们需要找到未移动元素的最大数量。这些元素是最长的连续序列,它是
(a0,a1,…an)
,其中
a(i+1)=ai+1

比如说,

(4,1,2,5,3),最长连续序列为(1,2,3)

(5,2,1,3,4),最长连续序列为(2,3,4)

所以我们有我们的代码:

int[]longest = new int[n + 1];
int result = 0;
for(int i = 0; i < n; i++){
    longest[data[i]] = longest[data[i] - 1] + 1;
    result = max (longest[data[i]] , result);
}

print "Minimum number of move is " + (n - result)
int[]最长=新的int[n+1];
int结果=0;
对于(int i=0;i
说明:

在代码中,我使用了一个数组
longest
,该数组的索引
ith
存储最长的连续序列,该序列以
值I
结束

因此,我们可以看到
longest[i]=longest[i-1]+1


最长连续序列的结果是存储在
longest
数组中的最大值。

在竞赛期间,我已经解决了Codeforces的这个问题。好问题

思考“最长连续子序列”
。答案是n-最长连续子序列。
例如: 以1237564为例。最长的连续子序列是1234。现在可以按特定顺序移动其余元素,以始终获得排序数组。至少直觉上我是这么想的


下面是主代码的一个片段:

    int n=in.readInt();
    int[] a=new int[n+1];
    int[] cnt=new int[n+1];
    int max=0;
    for(int i=0;i<n;i++)
        a[i]=in.readInt();
    for(int i=0;i<n;i++)
    {
        cnt[a[i]]=1+cnt[a[i]-1];
        max=Math.max(max,cnt[a[i]]);
    }
    out.printLine((n-max));
int n=in.readInt();
int[]a=新的int[n+1];
int[]cnt=新的int[n+1];
int max=0;

对于(int i=0;i我在竞赛期间解决了这个关于代码力的问题。这个问题很好。

想想“最长连续子序列”。答案是n-最长连续子序列。
例如: 以12375664为例。最长的连续子序列是1234。现在你可以按照特定的顺序移动剩余的元素来得到排序的数组。至少我直觉上是这样认为的


下面是主代码的一个片段:

    int n=in.readInt();
    int[] a=new int[n+1];
    int[] cnt=new int[n+1];
    int max=0;
    for(int i=0;i<n;i++)
        a[i]=in.readInt();
    for(int i=0;i<n;i++)
    {
        cnt[a[i]]=1+cnt[a[i]-1];
        max=Math.max(max,cnt[a[i]]);
    }
    out.printLine((n-max));
int n=in.readInt();
int[]a=新的int[n+1];
int[]cnt=新的int[n+1];
int max=0;

对于(int i=0;i认为你应该尝试快速排序。@art-我认为快速排序不会总是返回所需的最少移动次数。我认为你应该尝试快速排序的可能重复。@art-我认为快速排序不会总是返回所需的最少移动次数。可能重复的Thankyu Pham Trung这是正确的。你能解释一下吗更清楚的是?你是说解决方案是(n-最长连续子序列)?@RiderForest是的。你还不明白什么?我试图理解这些行“最长的[data[i]]=Longest[data[i]-1]+1;”和“result=max(最长的[data[i]],result);”谢谢Pham Trung这是正确的。你能解释得更清楚些吗?你是说解决方案是(n-最长的连续子序列)?@RiderForest是的。你还不明白什么?我试图理解这些行“最长的[data[i]]=最长的[data[i]-1]+1;”和“结果=最大值(最长的[data[i]],结果);”