优化最长公共序列的代码

时间:2012-05-22 12:39:49

标签: java algorithm optimization

我试图解决this practice problem,下面也引用了它。

  

厨师正计划为DirectiPlex就职典礼举办自助餐,   每个人都被邀请。在他们的路上,每位客人拿起一张纸   包含随机数的纸张(此数字可以重复)。该   然后客人和他们的朋友坐在圆桌旁。        厨师现在决定他想玩游戏。他要求你从你的桌子上挑选一个随机的人,并让他们阅读他们的   数字响亮。然后,围绕桌子顺时针移动每个人   会读出他们的号码。目标是找到那组数字   这形成了一个不断增加的后续序列。所有人都拥有这些   数字将有资格参加幸运抽奖!其中一个软件   开发人员对这一前景感到非常兴奋,并希望最大化   有资格参加抽奖的人数。所以,他   决定编写一个程序来决定谁应该阅读他们的号码   首先是为了最大限度地增加符合条件的人数   幸运抽奖。你能打败他吗?        输入第一行包含t,测试用例数(约15)。然后是t测试案例。每个测试用例包含两个   行:

     

第一行包含数字N,邀请的访客人数   派对。

     

第二行包含N个数字a1,a2,...,a分隔   空间,这是写在纸上的数字   顺时针顺序。          输出对于每个测试用例,打印包含单个数字的行,该数字是可以符合条件的最大访客数   参加幸运抽奖。

这是我提出的解决方案

// http://www.codechef.com/problems/D2/
import java.io.*;
import java.util.*;

public class D2
{
  public static void main(String [] args)
    throws IOException
  {
    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    int numTestCases = Integer.parseInt(br.readLine());
    for(int _t=0; _t<numTestCases; ++_t)
    {
      int N = Integer.parseInt(br.readLine());
      StringTokenizer strtok = new StringTokenizer(br.readLine());
      int [] originalArray = new int[N*2];
      for(int i=0; i<N; ++i)
      {
        //this concatenates the array with itself at the time of reading the input itself
        originalArray[i] = originalArray[N+i] = Integer.parseInt(strtok.nextToken());
      }
      //Now we calculate the length of the longest increasing sequence
      int maxWinners = new LongestIncreasingSequence(originalArray).lengthOfLongestIncreasingSequence();
      System.out.println(maxWinners);
    }
  }
}

class LongestIncreasingSequence
{
  private int [] array;
  private int [] longest;
  private int subsequence_size;
  public LongestIncreasingSequence(int [] A)
  {
    array = A;
    longest = new int[array.length / 2];
    longest[0] = array[0];
    subsequence_size = 1;
  }

  public int lengthOfLongestIncreasingSequence()
  {
    for(int i=1; i<array.length; ++i)
    {
      if(array[i] < longest[0])
      {
        longest[0] = array[i];
      }
      else if(array[i] > longest[subsequence_size - 1])
      {
        longest[subsequence_size++] = array[i];
      }
      else
      {
        //Make the replacement with binary search
        longest[getReplacementIndex(array[i])] = array[i];
      }
    }
    return subsequence_size;
  }

  //Method to find the correct index using binary search
  private int getReplacementIndex(int elem)
  {
    int left, right, mid;
    left = 0; right = subsequence_size - 1;
    while(right - left > 1)
    {
      mid = 1 + (right - left) / 2;
      if(array[mid] >= elem)
      {
        if(mid != right) right = mid;
        else --right;
      }
      else
      {
        left = mid;
      }
    }
    return right;
  }
}

复杂度为O(n(log(n))我通过将数组与自身连接来找到最长的序列。

然而,这并没有超出时间要求,有人可以帮助我加快这种实施。

1 个答案:

答案 0 :(得分:1)

我不会进行N轮换,而是一次性确定最长(循环)运行。这肯定是可行的,你只需要在阵列的末尾小心扭曲。