-1

私は最近仕事に応募し、要件はテストを完了してから面接することでした。テストのために2つの質問が出されましたが、これは非常に簡単で、うまくいきましたが、それでもスクリプトに時間がかかったためテストに失敗したと言われました実行が完了するまで 18 秒。これは、高速化するために他に何ができるかわかりません。私はテストに失敗しましたが、他にできることを知りたいですか? プログラム言語はPHPで、コマンドライン入力を使用して実行する必要がありました

ここに質問があります:

 K Difference
Given N numbers , [N<=10^5] we need to count the total pairs of numbers that have a difference of K. [K>0 and K<1e9]

Input Format:
1st line contains N & K (integers).
2nd line contains N numbers of the set. All the N numbers are assured to be distinct.
Output Format:
One integer saying the no of pairs of numbers that have a diff K.

Sample Input #00:
5 2
1 5 3 4 2

Sample Output #00:3
Sample Input #01:
10 1
363374326 364147530 61825163 1073065718 1281246024 1399469912 428047635 491595254 879792181 1069262793 
Sample Output #01:
0
Note: Java/C# code should be in a class named "Solution"
Read input from STDIN and write output to STDOUT.

そしてこれが解決策です

$fr = fopen("php://stdin", "r");
$fw = fopen("php://stdout", "w");

fscanf($fr, "%d", $total_nums);
fscanf($fr, "%d", $diff);

$ary_nums = array();
for ($i = 0; $i < $total_nums; $i++) {
    fscanf($fr, "%d", $ary_nums[$i]);
}

$count = 0;
sort($ary_nums);
for ($i = $total_nums - 1; $i > 0; $i--) {
    for ($j = $i - 1; $j >= 0; $j--) {
        if ($ary_nums[$i] - $ary_nums[$j] == $diff) {
            $count++;
            $j = 0;
        }
    }
}
fprintf($fw, "%d", $count);
4

2 に答える 2

3

アルゴリズムの実行時間は O(N^2) で、これは約 10^5 * 10^5 = 10^10 です。いくつかの基本的な観察により、約 10^5*16 = 1.6*10^6 のみである O(NlgN) に減らすことができます。

アルゴリズム:

  1. 配列 ary_nums をソートします。
  2. 配列の i 番目の整数ごとにバイナリ検索を行い、ary_nums[i]-K が配列に存在するかどうかを確認します。増加結果が存在する場合は、i 番目の整数をスキップします。

sort($ary_nums);

for ($i = $total_nums - 1; $i > 0; $i--) {

        $hi  = $i-1;
        $low = 0;
        while($hi>=$low){
            $mid = ($hi+$low)/2;
            if($ary_nums[$mid]==$ary_nums[$i]-$diff){
                $count++;
                break;
            }
            if($ary_nums[$mid]<$ary_nums[$i]-$diff){
                 $low = $mid+1;
            }
            else{
                 $hi  = $mid-1;
            }
        }
    }
}
于 2013-07-25T05:17:17.307 に答える
0

技術面接でも同じ質問を受けました。同じ会社の面接なのかしら。:)

とにかく、これが私が思いついた私の答えです(インタビューの後):

// Insert code to get the input here

$count = 0;
sort ($arr);

for ($i = 0, $max = $N - 1; $i < $max; $i++)
{
   $lower_limit = $i + 1;
   $upper_limit = $max;

   while ($lower_limit <= $upper_limit)
   {
      $midpoint = ceil (($lower_limit + $upper_limit) / 2);
      $diff = $arr[$midpoint] - $arr[$i];

      if ($diff == $K)
      {
         // Found it. Increment the count and break the inner loop.
         $count++;
         $lower_limit = $upper_limit + 1;
      }
      elseif ($diff < $K)
      {
         // Search to the right of midpoint
         $lower_limit = $midpoint + 1;
      }
      else
      {
         // Search to the left of midpoint
         $upper_limit = $midpoint - 1;
      }
   }
}

@Fallen: 次の入力でコードが失敗しました:

Enter the numbers N and K: 10 3
Enter numbers for the set: 1 2 3 4 5 6 7 8 9 10
Result: 6 

$mid(奇数を考慮していない)の計算に関係していると思います

于 2013-08-01T16:20:33.263 に答える