알고리즘 유형별 문제풀이 02.다양한 정렬 응용법 (Sort Application) 응용편 카테고리 :
한 번에 끝내는 코딩테스트 369 JAVA편 tag #
Fastcampusalgorithm 2022년 06월 14일 글
다양한 정렬 응용 (Sort Application) 응용편 정답의 최대치 출력: 0 ~ N - 1 \[N\leq50\] int 범위면 충분 시간, 공간 복잡도 계산하기 배열정렬 \[정렬은 \quad O\left(N \log N \right)\] P배열 구하기 \[순서대로 \; 채우면 \quad O\left(N\right)\] 복잡도 \[시간: \quad O\left(N \log N \right)\] \[공간: \quad O\left(N\right)\] 구현 public class baekjoon1015 {
static class NumberIdx implements Comparable < NumberIdx > {
int num ;
int idx ;
public NumberIdx ( int num , int idx ) {
this . num = num ;
this . idx = idx ;
}
@Override
public int compareTo ( NumberIdx o ) {
return this . num - o . num ;
//자바는 Object 원소 정렬이 Tim Sort이고 Tim Sort는 Stable 하기 때문에 NUM이 같으면 IDX 오름차순이 보장이 됨
}
}
public static void main ( String [] args ) throws IOException {
BufferedReader br = new BufferedReader ( new InputStreamReader ( System . in ));
int N = Integer . parseInt ( br . readLine ());
int [] P = new int [ N ];
NumberIdx [] B = new NumberIdx [ N ];
StringTokenizer st = new StringTokenizer ( br . readLine (), " " );
for ( int i = 0 ; i < N ; i ++) {
B [ i ] = new NumberIdx ( Integer . parseInt ( st . nextToken ()), i );
}
Arrays . sort ( B );
for ( int i = 0 ; i < N ; i ++) {
P [ B [ i ]. idx ] = i ;
}
for ( int i = 0 ; i < N ; i ++) {
System . out . print ( P [ i ] + " " );
}
}
}
자바는 Object 원소 정렬이 Tim Sort이고 Tim Sort는 Stable 하기 때문에 NUM이 같으면 IDX 오름차순이 보장이 된다는 것을 기억하자.
정답의 최대치 \[1\leq N \leq20,000\] int 범위면 충분 시간, 공간 복잡도 계산하기 배열정렬 \[정렬은 \quad O\left(N \log N \right)\] 배열 구하기 \[순서대로 \; 읽으면 \quad O\left(N\right)\] 복잡도 \[시간: \quad O\left(N \log N \right)\] \[공간: \quad O\left(N\right)\] 구현 public class baekjoon1181 {
static class Word implements Comparable < Word > {
String name ;
public Word ( String name ) {
this . name = name ;
}
@Override
public int compareTo ( Word o ) {
if ( this . name . length () != o . name . length ()) {
return this . name . length () - o . name . length ();
}
return name . compareTo ( o . name );
}
}
public static void main ( String [] args ) throws IOException {
BufferedReader br = new BufferedReader ( new InputStreamReader ( System . in ));
int N = Integer . parseInt ( br . readLine ());
Word [] words = new Word [ N ];
for ( int i = 0 ; i < N ; i ++) {
StringTokenizer st = new StringTokenizer ( br . readLine (), " " );
words [ i ] = new Word ( st . nextToken ());
}
Arrays . sort ( words );
for ( int i = 0 ; i < N ; i ++) {
if ( i == 0 || ! words [ i - 1 ]. name . equals ( words [ i ]. name )) {
System . out . println ( words [ i ]. name );
}
}
}
}
정답의 최대치 \[입출력 \; -2^{62} \sim 2^{62}\] int 범위로는 감당이 안됨 long 사용해야함 시간, 공간 복잡도 계산하기 배열정렬 \[정렬은 \quad O\left(N \log N \right)\] Counting \[순서대로 \; 읽으면 \quad O\left(N\right)\] 복잡도 \[시간: \quad O\left(N \log N \right)\] \[공간: \quad O\left(N\right)\] 구현 HashMap을 이용하면 더 쉽게 풀 수 있지만 정렬의 특성을 이용해서 풀이해 봄 같은 정보는 인접해 있다는 특성을 이용해서 풀이 public class baekjoon11652 {
public static void main ( String [] args ) throws IOException {
BufferedReader br = new BufferedReader ( new InputStreamReader ( System . in ));
int N = Integer . parseInt ( br . readLine ());
long [] numbers = new long [ N ];
for ( int i = 0 ; i < N ; i ++) {
StringTokenizer st = new StringTokenizer ( br . readLine (), " " );
numbers [ i ] = Long . parseLong ( st . nextToken ());
}
Arrays . sort ( numbers );
long mode = numbers [ 0 ];
int modeCount = 1 ;
int currentCount = 1 ; // mode: 최빈값, modeCount: 최빈값의 등장 횟수, currentCount: 현재 값(a[1])의 등장 횟수
for ( int i = 1 ; i < N ; i ++) {
if ( numbers [ i - 1 ] == numbers [ i ]) {
currentCount ++;
} else {
currentCount = 1 ;
}
if ( currentCount > modeCount ) {
mode = numbers [ i ];
modeCount = currentCount ;
}
}
System . out . println ( mode );
}
}
정답의 최대치 \[1\leq N \leq50,000\] int 범위면 충분 시간, 공간 복잡도 계산하기 배열정렬 \[정렬은 \quad O\left(N \log N \right)\] 배열 구하기 \[순서대로 \; 읽으면 \quad O\left(N\right)\] 복잡도 \[시간: \quad O\left(N \log N \right)\] \[공간: \quad O\left(N\right)\] 구현
public class baekjoon20291 {
public static void main ( String [] args ) throws IOException {
BufferedReader br = new BufferedReader ( new InputStreamReader ( System . in ));
int N = Integer . parseInt ( br . readLine ());
String [] list = new String [ N ];
for ( int i = 0 ; i < N ; i ++) {
String s = br . readLine ();
list [ i ] = s . split ( "\\." )[ 1 ];
}
Arrays . sort ( list );
StringBuilder sb = new StringBuilder ();
for ( int i = 0 ; i < N ; ) {
int cnt = 1 , j = i + 1 ;
for (; j < N ; j ++) {
if ( list [ j ]. compareTo ( list [ i ]) == 0 ) {
cnt ++;
} else break ;
}
sb . append ( list [ i ]). append ( " " ). append ( cnt ). append ( "\n" );
i = j ;
}
System . out . println ( sb );
}
}
정답의 최대치 \[점의\,개수\; N\leq50,000\] \[0\leq점의 위치\leq10^5=100,000\] \[0\leq점의\,색깔 \leq N\] \[점두개\,\Rightarrow 2 \times 10^5 \,만큼의\,화살표\,길이\,색깔마다\,이런\,점들이\,있다면\]총 5,000/2 쌍 만큼 만들 수 있음 즉 모든 점마다 10만 만큼의 길이를 갖는 화살표를 그리는 경우 \[정답의\,최대치:\, 5,000 \times 100,000 = 5 \times 10^8 \, \Rightarrow \, Integer로\,계산해도\,충분\] 시간, 공간 복잡도 계산하기 색깔별로 모으기 \[공간:\,ArrayList로 \quad O\left(N\right)\] 배열 정렬 \[정렬은 \quad O\left(N \log N \right)\] 정답 계산 \[점마다\,좌우만\,보니깐 \quad O\left(N\right)\] 복잡도 \[시간: \quad O\left(N \log N \right)\] \[공간: \quad O\left(N\right)\] 구현 각 원소마다, 가장 가까운 원소는 자신의 양옆 중에 있다는 특성을 이용해서 풀이
public class baekjoon15970 {
static int N ;
static ArrayList < Integer >[] lists ;
static int leftAdd ( int color , int idx ) {
if ( idx == 0 ) return Integer . MAX_VALUE ;
return lists [ color ]. get ( idx ) - lists [ color ]. get ( idx - 1 );
}
static int rightAdd ( int color , int idx ) {
if ( idx + 1 == lists [ color ]. size ()) return Integer . MAX_VALUE ;
return lists [ color ]. get ( idx + 1 ) - lists [ color ]. get ( idx );
}
public static void main ( String [] args ) throws IOException {
BufferedReader br = new BufferedReader ( new InputStreamReader ( System . in ));
N = Integer . parseInt ( br . readLine ());
lists = new ArrayList [ N + 1 ];
for ( int i = 1 ; i <= N ; i ++) {
lists [ i ] = new ArrayList < Integer >();
}
for ( int i = 1 ; i <= N ; i ++) {
StringTokenizer st = new StringTokenizer ( br . readLine (), " " );
int location = Integer . parseInt ( st . nextToken ());
int color = Integer . parseInt ( st . nextToken ());
lists [ color ]. add ( location );
}
int result = 0 ;
for ( int i = 1 ; i <= N ; i ++) {
Collections . sort ( lists [ i ]);
}
for ( int i = 1 ; i <= N ; i ++) {
for ( int j = 0 ; j < lists [ i ]. size (); j ++) {
int left = leftAdd ( i , j );
int right = rightAdd ( i , j );
result += Math . min ( left , right );
}
}
System . out . println ( result );
}
}
© 2020. All rights reserved.
SIKSIK