재귀함수와 정렬(4)

김민지·2023년 1월 14일
0

코딩테스트

목록 보기
21/31

2947

시간초과

  • 왜시간 초과가 나는지 모르겠었다
    flush를 해서 제대로 함수가 종료된줄알았는데 아니였다
    while문을 계속돌고있었다

시간초과 난 코드

import java.io.*;
import java.nio.Buffer;
import java.util.Arrays;

public class Main{

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
        String input[] = br.readLine().split(" ");
        int arr[] = new int[input.length];
        for(int i=0;i<input.length;i++){
            arr[i] = Integer.parseInt(input[i]);
        }
        boolean isRepeat = true;
        while(true){
            for(int i=0;i<input.length-1;i++){
                if(arr[i] > arr[i+1]) {
                    isRepeat = false;
                    int temp = arr[i];
                    arr[i] = arr[i+1];
                    arr[i+1] = temp;
                    for(int k=0;k<input.length;k++){
                        bw.write(arr[k] + " ");
                    }
                    bw.write("\n");
                    bw.flush();
                }
            }
            if(isRepeat) break;
        }
        System.out.println("asdas");
        for(int k=0;k<input.length;k++){
            bw.write(arr[k] + " ");
        }
        bw.write("\n");


        bw.flush();
        bw.close();
    }


}

for문을 돌면서 분명 isRepeat에 false가 넣어졌을것이다
그런데 나중에 12345여도, isRepeat가 true로 변경되는 일이 없기때문에 계속while문을 돌다가 시간초과가나는것이다

1431

'7'-'0' 의 결과가 7인 이유

  • 문자 '7'에서 '0'을 빼면 7이 됩니다
    이 이유는 -라는 연산자를 쓸때 보통 int보다 작은 자료형의 경우에
    int형으로 변환이 이루어지는데
    '7'의 아스키 코드값 빼기 '0'의 아스키코드값을빼서 정수형으로 변환하게 될 경우에 7이 나오기때문인가요?
    그러니까
  • 문자가 내부적으로 숫자로 저장된다는 점
  • 연산자를 사용할때 int보다 작은 자료형을 사용하면 int로 변환된다는점
  • '1'~'9'까지의 아스키코드값이 연속적이라는점

퀵정렬

import java.io.*;
import java.lang.reflect.Array;
import java.nio.Buffer;
import java.util.Arrays;

public class Main{
    //p1번째의 arr 값과 p2번째의 arr값을 swap시킨다
    public static void swap(int arr[], int p1, int p2){
        int temp = arr[p2];
        arr[p2] = arr[p1];
        arr[p1] = temp;
    }
    //pivot기준 pivot왼쪽값은 pivot보다작게, pivot오른쪽값은 pivot보다 크게 정렬하고
    //pivot의 idx를 반환해준다
    public static int partition(int arr[], int left, int right){
        //로무스 알고리즘에따라 i는 left보다 한칸적게, j는 left에서 시작한다
        int i = left-1;
        //pivot은 가장오른쪽에 있는 값으로 세팅해준다
        int pivot = arr[right];
        //pivot직전까지만 검사하면된다. pivot보다 작은값을왼쪽에 큰값을오른쪽에 배치시키려고하는 for문이니깐
        for(int j=left;j<=right-1;j++){
            //등호가 있어야할지 없어야할지 잘 모르겠음
            //있든 없든 상관없는거아닌가? - 상관없음
            //아래의 행위는 pivot보다 큰값을 오른쪽에 작은값을 왼쪽에 배치하려는 행위이다
            //그래서 pivot과 같은값이 있으면 그 값은 오른쪽에 오든 왼쪽에 오든 상관이 없다. 그렇기때문에
            //등호를 붙이든 안붙이든 정답이뜨는것이다
            if(arr[j] < pivot){
                //i+1해주고 i랑j의 값을 바꾼다
                //i는 j가 이미 지나간값들이다. 즉 pivot보다 큰값들이여서 무조건 교체해야했던 것들이엇다
                //드디어 작은값이 나왔으니 작은값과 큰값을 교환해준다
                i++;
                swap(arr, i, j);
            }
        }
        //pivot의 값을 i+1에 위치시켜야함
        swap(arr, i+1, right);
        //i번째를 포함한그 왼쪽은 pivot보다 작은값임
        //pivot의 위치는 i+1이 될것임
        return i+1;
    }
    public static void quickSort(int arr[], int left, int right){
        //종료조건이 필요함.
        //나누다보면 한칸짜리인거까지 나누게 될거고 그런경우를 제외시켜주면됨
        if(left < right){
            //arr를 적당히 쪼개서 x를 반환시켜주는것이기때문에
            int x = partition(arr, left, right);
            //재귀함수마다 left<right여야한다는 조건이 필요함
            quickSort(arr, left, x-1);
            quickSort(arr, x+1, right);
        }

    }
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
        int n = Integer.parseInt(br.readLine());
        int arr[] = new int[n];
        for(int i=0;i<n;i++){
            arr[i] = Integer.parseInt(br.readLine());
        }
        quickSort(arr, 0, arr.length-1);
        for(int i=0;i<n;i++){
           bw.write(arr[i]+"\n");
        }
        bw.flush();
        bw.close();
    }


}
profile
안녕하세요!

0개의 댓글