##解決しました!
java初心者のヤスです!
AtCoder ABC234 D をようやっと解決しました!
どこでつまづいて、どうやって解決したかをまとめています。
問題はこちら↓
##つまづいたところ
・split()でわざわざ全部読み込んでいた。
・配列とListの多様
・StringBuilder知らなかった。
・そもそもの考え方
##いまだにイマイチわからんこと
・平衡二分探索
・log回の概念
###split()でわざわざ全部読み込んでいた。
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改行された数列を読み込むコードですが...
これだと一行読み込んで、空白で分割して、変数に入れたり配列に一つ一つ入れていく作業をしていますが...
あぁ〜!nextInt()使えばええのかぁ〜!
空白あっても使えるんか〜!
リファレンスに使えるって書いてある〜〜〜
あぁ〜〜
ということで使いました!変えたのがこちら↓
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 さんめっちゃ参考になりました!ありがとうございました!
やっていることは同じでもやっぱり処理速度違うもんなんだな...
###StringBuilder知らなかった
System.out.println();
の繰り返し出力が案外遅かったらしい。
詳しくはわかりませんが、1回1回メソッド?を呼び出してどうのこうの...といった理由みたいです。
ということで、StringBuilderをつかって数字を保持、最後にまとめて出力という形にしました!
保持の形と出力のコードはこちら↓
//PriorityQueueの先頭と改行コードを保持
ans.append(iQlist.peek() + "\n");
//toStringを使って出力
System.out.println(ans.toString());
###そもそもの考え方
データをこねくり回していたのが原因でした
入力値
↓
一行ずつ読み取る
↓
NとKをintに変換して変数に代入
数列は配列に全部代入
↓
配列からK個分取り出して配列に代入
↓
その配列の最小値を見つける
↓
最小値を出力
↓
最小値とK+1番目の数字を比べる
↓
大きければ最小値を削除
↓
K+1番目の数字を配列に追加
↓
最小値出力
N番目まで繰り返し
というのを
入力
↓
nextInt();でNとKにそれぞれ代入
↓
nextInt();でK個分のみPriorityQueueに代入
↓
先頭をStringBuilderに保持(最小値を保持)
↓
★nextInt();でK+1....を読み込む
↓
保持した最小値とK+1番目の数字を比べる
↓
(小さい場合何もしない)
大きい場合
最小値削除
↓
K+1番目を配列に追加
↓
先頭を保持
★からN番目まで繰り返し
↓
保持した数字を出力
といった感じです。
ポイントは
『数列全て配列に入れ込まなくても入力値つかえばええやん』
ということ
nextInt();の性質をもっと知っていれば思いついた考え方だったかなと!
配列やlistを無くしてPriorityQueue1つだけでできました!
(そりゃ早くなるわ)
###最後に
最後にクリアしたコードがこちら↓
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);
//一行目の数字2つを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+1から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();
}
}
ありがとうございました!!
データ構造とか平衡二分探索はもうすこしじかんがかかりそうやな。