🎯
【Java】しゃくとり法の応用
例題
昇順にソートされた長さn
の配列a
があります。
配列の要素a[i]
に整数k
を与えた場合のa[i] + k
以下となる配列a
の要素の個数を求めよ。
例題の値
n = 5
k = 2
a = [1, 2, 3, 4, 5]
例題の答え
i = 0 の時
a[0] + k = 1 + 2 = 3
3以下となる要素の個数は[1,2,3]の3個
i = 1 の時
a[1] + k = 2 + 2 = 4
4以下となる要素の個数は[1,2,3,4]の4個
i = 2 の時
a[2] + k = 3 + 2 = 5
5以下となる要素の個数は[1,2,3,4,5]の5個
i = 3 の時
a[3] + k = 4 + 2 = 6
6以下となる要素の個数は[1,2,3,4,5]の5個
i = 4 の時
a[4] + k = 5 + 2 = 7
7以下となる要素の個数は[1,2,3,4,5]の5個
例題におけるしゃくとり法のアルゴリズム
- 右端のインデックスを表す変数を
r
を0
で初期化します。 - 左端のインデックスを表す変数
l
を0
からn - 1
まで繰り返すfor
文を定義します。 - 条件式が、
r
がn
より小さく、かつ、a[l]
にk
を加えてもa[r]
を超えないというwhile
文を定義します。 - 条件式を満たす場合、右端
r
を1
進めます。 - 条件式を満たさない場合、
r
を出力します。 - 条件式が、
l == r
というif
文を定義します。 - 条件式を満たす場合、右端の
r
を1
進めます。 - 条件式を満たさない場合、
l
を1
進めた状態で、2.
以降のfor
文に戻ります。
コード例
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n, k;
n = sc.nextInt();
k = sc.nextInt();
int[] a = new int[n];
for (int i = 0; i < n; i++) {
a[i] = sc.nextInt();
}
// 右端のインデックスの変数を r を 0 で初期化
int r = 0;
// 左端のインデックスの変数 l を 0 から n - 1 まで繰り返す
for (int l = 0; l < n; l++) {
// r が n より小さく、a[l] に k を加えても a[r] を超えない間
while (r < n && a[r] <= a[l] + k) {
// 右端 r を 1 進めます
r++;
}
// r を出力
System.out.println(r);
// もし l が r と同じなら
if (l == r) {
// r を 1 進めます
r++;
}
}
}
}
入力値
5 2
1 2 3 4 5
出力結果
3
4
5
5
5
Discussion