解決！！AtCoder ABC234 D java　クリア！！

##解決しました！
java初心者のヤスです！
AtCoder ABC234 D　をようやっと解決しました！

どこでつまづいて、どうやって解決したかをまとめています。
問題はこちら↓

https://atcoder.jp/contests/abc234/tasks/abc234_d

##つまづいたところ
・split()でわざわざ全部読み込んでいた。
・配列とListの多様
・StringBuilder知らなかった。
・そもそもの考え方

##いまだにイマイチわからんこと
・平衡二分探索
・log回の概念

###split()でわざわざ全部読み込んでいた。

```java:java
String[] NK = sc.nextLine().split(" ");
int N = Integer.parseInt(NK[0]);
int K = Integer.parseInt(NK[1]);

//中略

int numlist[] = Arrays.stream(sc.nextLine().split(" ")).mapToInt(Integer::parseInt).toArray();

```
NとK改行された数列を読み込むコードですが...
これだと一行読み込んで、空白で分割して、変数に入れたり配列に一つ一つ入れていく作業をしていますが...

やっぱ作業量多い..なんかないかな..![スクリーンショット 2022-01-22 16.34.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2510911/1d9787ad-7a91-2a25-53a2-c0c29ef4953f.png)

あぁ〜！nextInt()使えばええのかぁ〜！
空白あっても使えるんか〜！
リファレンスに使えるって書いてある〜〜〜
あぁ〜〜

ということで使いました！変えたのがこちら↓

```java:java
int N = sc.nextInt();
int K = sc.nextInt();
//中略
for(int i = 0; i < K; i++) {
	iQlist.add(sc.nextInt());
}
```
ということでだいぶ圧縮できた！
@yucatio 　さんありがとうございました！

分割しなくていいし、intに変換しなくていいし、そもそも考え方で配列いらないし。

for文のところは配列からK個分をPriorityQueueにそのまま入れてます！


###配列とListの多様

当初は数字を一気に読み込んでsplit(" ");で空白区切りにして配列に入れ込んでInteger.ParthIntしてIntのListにいれて...

みたいに破滅的に面倒なことをしていました...

読み取りに関しては前述の通りで
List使いすぎ問題はPriorityQueueで解決しました！

こういう時PriorityQueueって便利ですね〜

@PondVillege さんめっちゃ参考になりました！ありがとうございました！
![スクリーンショット 2022-01-22 17.40.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2510911/fca27a9a-55cf-b352-5cd3-7bdd189e8e43.png)

やっていることは同じでもやっぱり処理速度違うもんなんだな...


###StringBuilder知らなかった

System.out.println();
の繰り返し出力が案外遅かったらしい。
詳しくはわかりませんが、１回１回メソッド？を呼び出してどうのこうの...といった理由みたいです。

ということで、StringBuilderをつかって数字を保持、最後にまとめて出力という形にしました！

保持の形と出力のコードはこちら↓

```java:java
//PriorityQueueの先頭と改行コードを保持
ans.append(iQlist.peek() +  "\n");

//toStringを使って出力		
System.out.println(ans.toString());
		
```

###そもそもの考え方

データをこねくり回していたのが原因でした

入力値
↓
一行ずつ読み取る
↓
NとKをintに変換して変数に代入
数列は配列に全部代入
↓
配列からK個分取り出して配列に代入
↓
その配列の最小値を見つける
↓
最小値を出力
↓
最小値とK＋１番目の数字を比べる
↓
大きければ最小値を削除
↓
K+1番目の数字を配列に追加
↓
最小値出力
N番目まで繰り返し



というのを

入力
↓
nextInt();でNとKにそれぞれ代入
↓
nextInt();でK個分のみPriorityQueueに代入
↓
先頭をStringBuilderに保持（最小値を保持）
↓
★nextInt();でK+１....を読み込む
↓
保持した最小値とK+1番目の数字を比べる
↓
（小さい場合何もしない）
大きい場合
最小値削除
↓
K+1番目を配列に追加
↓
先頭を保持
★からN番目まで繰り返し
↓
保持した数字を出力


といった感じです。
ポイントは
『数列全て配列に入れ込まなくても入力値つかえばええやん』
ということ
nextInt();の性質をもっと知っていれば思いついた考え方だったかなと！
配列やlistを無くしてPriorityQueue１つだけでできました！
（そりゃ早くなるわ）

###最後に
最後にクリアしたコードがこちら↓

```java:java
import java.util.PriorityQueue;
import java.util.Queue;
import java.util.Scanner;

public class Main {
	public static void main(String[] args) {
		
		Scanner sc = new Scanner(System.in);
		//一行目の数字２つをNとKに代入
		int N = sc.nextInt();
		int K = sc.nextInt();
		
        
		Queue<Integer> iQlist = new PriorityQueue<Integer>();
		StringBuilder ans = new StringBuilder();
		
        //2行目の先頭からK個分をPriorityQueueに追加
        for(int i = 0; i < K; i++) {
			iQlist.add(sc.nextInt());
		}
        //最小値を保持
		ans.append(iQlist.peek() +  "\n");
		//K＋１からNまで繰り返し
		for(int j = K; j < N; j++) {
			int kNext = sc.nextInt();

            //最小値とK+1...を比べる
			if(kNext > iQlist.peek()) {
                //先頭削除
				iQlist.poll();
                //K+1...を追加
				iQlist.add(kNext);
			}
            //最小値を保持
			ans.append(iQlist.peek() +  "\n");
		}
        //保持した数字を全部出力
		System.out.println(ans.toString());
		sc.close();
	}
}
```

ありがとうございました！！

データ構造とか平衡二分探索はもうすこしじかんがかかりそうやな。