반응형

문제 설명

괄호가 바르게 짝지어졌다는 것은 '(' 문자로 열렸으면 반드시 짝지어서 ')' 문자로 닫혀야 한다는 뜻입니다. 예를 들어

"()()" 또는 "(())()" 는 올바른 괄호입니다.
")()(" 또는 "(()(" 는 올바르지 않은 괄호입니다.
'(' 또는 ')' 로만 이루어진 문자열 s가 주어졌을 때, 문자열 s가 올바른 괄호이면 true를 return 하고, 올바르지 않은 괄호이면 false를 return 하는 solution 함수를 완성해 주세요.

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

나의 풀이 (java)

import java.util.Stack;

class Solution {

    public static void main(String[] args) {
        String str = "()()";
        boolean result = solution(str);
        System.out.println("### Result : " + result);
    }

    static boolean solution(String s) {
				boolean answer = false;
        Stack<Integer> criteria = new Stack<>();

        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);
            if (c == '('){
                criteria.push(0);
            }else if (c == ')'){
                if (criteria.empty()) return false;
                criteria.pop();
            }
        }

        // split의 경우 효율성 검사에서 떨어짐
//        if (s.length()==0) return false;
//        String[] strArr = s.split("");
//        for (String str:strArr) {
//            if (str.equals("(")){
//                criteria.push(0);
//            }else if (str.equals(")")){
//                if (criteria.empty()) return false;
//                criteria.pop();
//            }
//        }

        if (criteria.empty()) answer = true;
        return answer;
    }
}

풀이 방법

  • 간단한 Stack 사용 pop,push 사용법
  • 문자열 for문을 사용법

다른사람의 풀이 (java)

Godd Idea :

느낀점

  • 문자 for문 사용시, split(””)대신 charAt()으로 사용 (char은 ‘’로 문자열 비교)
    • split으로 문자열 반복문을 사용 할 경우, 효율성에서 통과하지 못하고, 자바 버전에 따라 문제가 생기기도 하니, charAt()을 사용하자!
반응형
반응형

문제 설명

당신은 폰켓몬을 잡기 위한 오랜 여행 끝에, 홍 박사님의 연구실에 도착했습니다. 홍 박사님은 당신에게 자신의 연구실에 있는 총 N 마리의 폰켓몬 중에서 N/2마리를 가져가도 좋다고 했습니다.
홍 박사님 연구실의 폰켓몬은 종류에 따라 번호를 붙여 구분합니다. 따라서 같은 종류의 폰켓몬은 같은 번호를 가지고 있습니다. 예를 들어 연구실에 총 4마리의 폰켓몬이 있고, 각 폰켓몬의 종류 번호가 [3번, 1번, 2번, 3번]이라면 이는 3번 폰켓몬 두 마리, 1번 폰켓몬 한 마리, 2번 폰켓몬 한 마리가 있음을 나타냅니다. 이때, 4마리의 폰켓몬 중 2마리를 고르는 방법은 다음과 같이 6가지가 있습니다.

나의 풀이 (java)

import java.util.HashSet;
class Solution {
    public int solution(int[] nums) {
        HashSet<Integer> tempSet = new HashSet<>();
        for(int i =0; i<nums.length;i++) {
            tempSet.add(nums[i]);
        }

        // map 크기 중 arr/2 크기 만큼 해서 최댓값 구하기
        int kindCount = tempSet.size();
        int selectCount = nums.length/2;
        return Math.min(kindCount, selectCount);
    }
}

풀이 방법 = 다른사람의 풀이 (java)

Godd Idea :

  • HashSet 를 사용한 중복 제거 (HashSet = Array List와 비슷하지만 중복 제외,성능도 더 좋음)

느낀점

HashMap만 썼는데,
이런 경우에는 굳이 Map이 아닌 Set으로 처리 가능하다는 것과 쓰는 법을 배웠다

반응형
반응형

문제 설명

스파이들은 매일 다른 옷을 조합하여 입어 자신을 위장합니다.

예를 들어 스파이가 가진 옷이 아래와 같고 오늘 스파이가 동그란 안경, 긴 코트, 파란색 티셔츠를 입었다면 다음날은 청바지를 추가로 입거나 동그란 안경 대신 검정 선글라스를 착용하거나 해야 합니다.

종류 이름
얼굴 동그란 안경, 검정 선글라스
상의 파란색 티셔츠
하의 청바지
겉옷 긴 코트
스파이가 가진 의상들이 담긴 2차원 배열 clothes가 주어질 때 서로 다른 옷의 조합의 수를 return 하도록 solution 함수를 작성해주세요.

나의 풀이 (java)

import java.util.HashMap;
class Solution {
    public int solution(String[][] clothes) {
        int answer = 1;
        HashMap<String, Integer> clothesMap = new HashMap<>();
        // Hash로 저장
        for (int i = 0; i < clothes.length; i++) {
            clothesMap.put(clothes[i][1], clothesMap.get(clothes[i][1])==null ? 2:clothesMap.get(clothes[i][1])+1);
        }

        // Hash를 이용해 key(카테고리), value(count++) 해서 count 계산
        for (String category :clothesMap.keySet()) {
            answer *= clothesMap.get(category);
        }

        // count들 끼리 곱 한후 -1 (모두 0을 고른 경우)
        return answer-1;
    }
}

풀이 방법 = 다른사람의 풀이 (java)

Godd Idea :

  • Hash로 중복 제거
  • Hash를 이용해 key(카테고리), value(count++) 해서 count 계산
  • 경우의수 구하기 : 수학적 접근 (n+1) * (m+1) * (o+1)... -1

느낀점

HsahMap은 key, value로 이루어지는데, key가 중복되지 않는걸 이용해서 중복제거, key별로 관리하는 방식으로 사용 (count)

반응형
반응형

문제 설명

전화번호부에 적힌 전화번호 중, 한 번호가 다른 번호의 접두어인 경우가 있는지 확인하려 합니다.
전화번호가 다음과 같을 경우, 구조대 전화번호는 영석이의 전화번호의 접두사입니다.

  • 구조대 : 119
  • 박준영 : 97 674 223
  • 지영석 : 11 9552 4421

전화번호부에 적힌 전화번호를 담은 배열 phone_book 이 solution 함수의 매개변수로 주어질 때, 어떤 번호가 다른 번호의 접두어인 경우가 있으면 false를 그렇지 않으면 true를 return 하도록 solution 함수를 작성해주세요.

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

나의 풀이 (java)

import java.util.Arrays;

public class Phonebook {

    public static void main(String[] args) {
        String[] phone_book = {"12", "123", "1235", "567", "88"};
        System.out.println("###    RESULT  : "+ solution(phone_book));
    }

    // String 정렬(12,123,1235,222,..) 후 비교
    public static boolean solution(String[] phone_book) {
        Arrays.sort(phone_book);
        for (int i = 0; i < phone_book.length-1; i++) {
            if(phone_book[i+1].startsWith(phone_book[i])) return false;
        }
        return true;
    }

    // 이중 for문 사용 - 효율성 테스트에서 걸림
    public static boolean solution2(String[] phone_book) {
        for (int i = 0; i < phone_book.length; i++) {
            for (int j = 0; j < phone_book.length; j++) {
                if(i != j && phone_book[i].startsWith(phone_book[j])) return false;
            }
        }
        return true;
    }
}

풀이 방법

예전에 다른 사람의 풀이를 봤던게 어렴풋이 기억에 남아서 비슷하게 사용한 것 같다

중요 아이디어는 

  • startWith : 문자열의 prefix(접두사) 확인 가능
  • Array.Sort(문자) : 문자를 비교하면 1, 12, 123 이런식으로 정렬된다는 특징을 사용

다른사람의 풀이 (java) 

class Solution {
    public boolean solution(String[] phoneBook) {
        Arrays.sort(phoneBook);
        boolean result = true;
        for (int i=0; i<phoneBook.length-1; i++) {
            if (phoneBook[i+1].contains(phoneBook[i])) {
                result = false;
                break;
            }
        }
        return result;
    }
}

Godd Idea : String 정렬의 특징을 이용한 비교

느낀점

  • 해시를 사용하기전 Sorting을 통해 성능만 높이는게 성능을 위한 옵션이 아니라, 
    필수 사항이 되기도 한다
반응형
반응형

문제 설명

초 단위로 기록된 주식가격이 담긴 배열 prices가 매개변수로 주어질 때, 가격이 떨어지지 않은 기간은 몇 초인지를 return 하도록 solution 함수를 완성하세요.

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

나의 풀이 (java)

import java.util.ArrayList;
import java.util.List;

public class StockPrices {

    public static void main(String[] args) {
        int[] arr = {1,2,3,2,3};
        solution(arr);
    }

    public static int[] solution(int[] prices) {
        List<Integer> secondsArr = new ArrayList<>();
        for (int i = 0; i < prices.length; i++) {
            int seconds = 0;
            for (int j = i; j < prices.length; j++) {
                if (prices[i] > prices[j] || j == prices.length-1) {
                    secondsArr.add(seconds);
                    break;
                }else{
                    seconds ++;
                }
            }
        }
        return secondsArr.stream().mapToInt(Integer::intValue).toArray();
    }
}

풀이 방법

특별히 어려운 로직은 없고, 스택/큐의 문제임을 무시하고, 이중 for문으로 해결 가능

  • List -> Array
    list.stream().mapToInt(Integer::intValue).toArray();

다른사람의 풀이 (java) 

class Solution {
    public int[] solution(int[] prices) {
        int len = prices.length;
        int[] answer = new int[len];
        int i, j;
        for (i = 0; i < len; i++) {
            for (j = i + 1; j < len; j++) {
                answer[i]++;
                if (prices[i] > prices[j])
                    break;
            }
        }
        return answer;
    }
}

Godd Idea : 거의 비슷. seconds 변수를 사용하지 않고 바로 index로 접근해서 카운트하고, 조건문이 조금 다른게 차이

느낀점

  • 스택/큐를 사용하지 않는대신, 아래 2가지 방법을 사용 가능
    • temp 변수에 이전 값 or 이전까지의 특정값(최대값 등)을 저장해서 비교/처리 가능
    • 이중 for문 등을 사용하되, list의 index로 값에 직접 접근 : arr[i]++;
  • 물론 코드 짜고, 정리하지 않아 지저분한걸 감안해도, 코드가
    가독성이 떨어지고,
    그렇다고 재사용성이 좋지도 않고,
    아이디어가 좋은 것도 아니고,
    그냥 문제를 푼 느낌이 없지 않아 있다
  • 하지만, 코드를 직독직해 하듯이 풀었기에, 초보자가 보기에는 오히려 편할수도?!

 

반응형
반응형

문제 설명

배열 arr가 주어집니다. 배열 arr의 각 원소는 숫자 0부터 9까지로 이루어져 있습니다. 이때, 배열 arr에서 연속적으로 나타나는 숫자는 하나만 남기고 전부 제거하려고 합니다. 단, 제거된 후 남은 수들을 반환할 때는 배열 arr의 원소들의 순서를 유지해야 합니다. 예를 들면,

  • arr = [1, 1, 3, 3, 0, 1, 1] 이면 [1, 3, 0, 1] 을 return 합니다.
  • arr = [4, 4, 4, 3, 3] 이면 [4, 3] 을 return 합니다.

배열 arr에서 연속적으로 나타나는 숫자는 제거하고 남은 수들을 return 하는 solution 함수를 완성해 주세요.

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

나의 풀이 (java)

import java.util.ArrayList;
import java.util.List;

public class DeleteDuplicate {

    public static void main(String[] args) {
        int[] arr = {1,1,3,3,0,1,1};
        solution(arr);
    }

    public static int[] solution(int []arr) {
        List<Integer> list = new ArrayList<>();
        for (int i = 0; i < arr.length; i++) {
            if(i == 0 || arr[i] != arr[i-1]) {
                list.add(arr[i]);
            }
        }
        // Stream을 이용한 List -> int[]
        return list.stream().mapToInt(Integer::intValue).toArray();
    }

}

 

풀이 방법

특별히 어려운 로직은 없고, 아래 2가지만 잘 생각하면 된다

  • 중복 여부 확인 : arr의 index로 이전 값으로 접근해서 중복 여부 체크
  • list <-> array 변환 : 기본형(Integer)이 아닌 int형의 배열로 바꾸기 위해 Stream 사용 

다른사람의 풀이 (java) 

    public int[] solution(int []arr) {
        ArrayList<Integer> tempList = new ArrayList<Integer>();
        int preNum = 10;
        for(int num : arr) {
            if(preNum != num)
                tempList.add(num);
            preNum = num;
        }       
        int[] answer = new int[tempList.size()];
        for(int i=0; i<answer.length; i++) {
            answer[i] = tempList.get(i).intValue();
        }
        return answer;
    }

Godd Idea : 중복 여부를 확인할때, arr의 인덱스가 아닌 이전 값 체크용(preNum) 변수 사용하는게 키포인트

느낀점

 

반응형
반응형

Array → List

원배열을 바꾸면, 복사한 배열도 변경하고 싶은지의 여부에 따라 선택

  • Arrays.asList(arr)
    얕은 복사(원 배열 공유=동기화) List<String> list = Arrays.asList(arr)
  • new ArrayList<>(Arrays.asList(arr))
    깊은복사(새로운 배열=비동기화) List<String> list = Arrays.asList(arr)
  • Collector.toList()
    Stream 사용 List<String> list = Stream.of(arr).collect(Collectors.toList());

List → Array

  • toArray() String arr[] = arrList.toArray(new String[Size])
    Object[]로 리턴이라, 타입 변환이 어려움
  • toArray(T[] t)
    위와 똑같지만 T 타입의 배열 명시 하지만 기본형만 가능(int, double, float은 불가능) [길이] : 길은 size를 직접 넣어도 되고, 0으로 넣으면 자동 조정
  • Stream
    int 등으로 저장할때 유용(Integer→intValue로 int형변환→toArray사용) list.stream().mapToInt(Integer::intValue).toArray();
반응형
반응형

상황

spring으로 만든 서비스가 정상적으로 동작하다가,
작업이 안 되는 경우가 발생해서 로그를 찾아보니, 아래의 내용이 남아있음

 

에러내용

Cause: java.sql.SQLTransientConnectionException:  Lost connection to backend server: network error (server1: Connection reset by peer)

Lost connection to backend server: network error (server1: Connection reset by peer); nested exception is java.sql.SQLTransientConnectionException: Lost connection to backend server: network error (server1: Connection reset by peer)

 

예상 원인

  • 원격 서버에서 Connection을 reset 처리하거나
  • 종료된 커넥션을 재사용하려고 할때
  • 클라이언트(브라우저)에서 정지버튼을 누르거나, 브라우저를 종료하거나, 다른 화면으로 이동하는 등의 이유로 서버 측에서 작업 결과를 전달할 곳이 없어졌을 때
  • Connection에서 Timeout 발생
  • 메모리부족
  • 소켓 고갈 등등…

 

원인

근본적인 원인 

위의 예상원인 모두 실제 원인의 보기이고,
회사에서 해당 이슈가 종종 발생하는 원인은 DB서버의 작업이 있는 경우에 많이 발생

 

DB 서버의 특정 작업(백업, 데이터 이동 등등 IO나 리소스를 많이 잡아먹는 작업)이 진행중

=> DB의 성능저하

=> 평소에 문제없던 쿼리가 실행되지 못하고 타임아웃

조치

근본적인 조치

근본적인 원인을 해결해야 함

DB 서버의 작업 종료 or 해결 : 리소스가 많이 필요한 해당 작업을 빨리 종료 시키면 정상적으로 동작함

하지만 주기적으로 해야하는 작업이라면

쿼리나 서비스 성능 개선을 통해 어느정도 커버할 수 있음

 

쿼리 튜닝으로 해결

타임 아웃 (시간제한) 을 길게 설정하는 방법도 있지만, 근본적으로 쿼리 실행시간이 너무 오래 걸림

평소에는 0.5초도 걸리지 않았지만, 특정상황에서 계속 타임아웃이 나서 튜닝 필요성이 없었음

=> 주기적으로 발생할 것으로 추측돼서, 쿼리 튜닝실행

=> 평소에는 크게 차이 나지 않지만, (최악의 경우에서) 더 효율적인 인덱스를 타면서 쿼리가 개선

=> 같은 상황에서는 더이상 발생하지 않음

반응형
반응형

문제 설명

0 또는 양의 정수가 주어졌을 때, 정수를 이어 붙여 만들 수 있는 가장 큰 수를 알아내 주세요.
예를 들어, 주어진 정수가 [6, 10, 2]라면 [6102, 6210, 1062, 1026, 2610, 2106]를 만들 수 있고, 이중 가장 큰 수는 6210입니다.
0 또는 양의 정수가 담긴 배열 numbers가 매개변수로 주어질 때, 순서를 재배치하여 만들 수 있는 가장 큰 수를 문자열로 바꾸어 return 하도록 solution 함수를 작성해주세요.

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

다른사람의 풀이 (java) = 나의 풀이

import java.util.Arrays;
import java.util.Comparator;

class Solution {
    public String solution(int[] numbers) {

        // 숫자를 문자열로 변환
        String[] result = new String[numbers.length];
        for (int i = 0; i < numbers.length; i++) {
            result[i] = String.valueOf(numbers[i]);
        }

        // 정렬
        Arrays.sort(result, (o1, o2) -> (o2 + o1).compareTo(o1 + o2));

        // 0만 여러개 있는 배열의 경우 하나의 0만 리턴
        if (result[0].equals("0")) {
            return "0";
        }

        String answer = "";
        // 정렬된 문자 하나로 합치기
        for (String a : result) {
            answer += a;
        }
        return answer;
    }
}

풀이 방법

몇몇 테스트 케이스를 통과하지 못하고.. 1시간 정도 고민하다가, 결국 다른 사람의 풀이를 보고 풀었다

관건은 실제로 정렬을 구현하는 부분이었다. 

혼자 힘으로 풀때는 문자 3 vs 30 이 나올때 330이 출력되도록 하는 로직 고민하다가 시간을 다 써버림..

 

중요 포인트 - 두개의 문자를 합쳐 만드는 수의 대소 비교

Arrays.sort(result, (o1, o2) -> (o2 + o1).compareTo(o1 + o2))

 

느낀점

  • Array 정렬 방법
    • 단순 정렬시 - Array.sort(arr)
    • 복잡 정렬시 - Arrays.sort(result, (o1, o2) -> (o2 + o1).compareTo(o1 + o2))

 

반응형
반응형

문제 설명

H-Index는 과학자의 생산성과 영향력을 나타내는 지표입니다. 어느 과학자의 H-Index를 나타내는 값인 h를 구하려고 합니다. 위키백과1에 따르면, H-Index는 다음과 같이 구합니다.
어떤 과학자가 발표한 논문 n편 중, h번 이상 인용된 논문이 h편 이상이고 나머지 논문이 h번 이하 인용되었다면 h의 최댓값이 이 과학자의 H-Index입니다.
어떤 과학자가 발표한 논문의 인용 횟수를 담은 배열 citations가 매개변수로 주어질 때, 이 과학자의 H-Index를 return 하도록 solution 함수를 작성해주세요.

https://school.programmers.co.kr/learn/courses/30/lessons/42747

 

나의 풀이 (java)

import java.util.ArrayList;
import java.util.Collections;

class Solution {
    public int solution(int[] citations) {
        int answer = 0;
        ArrayList<Integer> citationList = new ArrayList();
        for(int num : citations) {citationList.add(num);}
        Collections.sort(citationList, Collections.reverseOrder());

        if(citationList.get(0)==0) return 0;

        for(int h=citationList.size()-1; h>=0; h--){
            if(h < citationList.get(h)){
                answer = h+1;
                break;
            }
        }
        return answer;
    }
}

내가 사용한 방법

배열을 한번 역순 정렬(큰수가 가장 앞) => 큰 수에서 하나씩 빼면서 조건에 맞는지 확인 => 예외 추가(길이가 ==0 종료)

여기서, 조건이 중요한 로직 포인트인데

  • 큰수부터 작은수로 정렬했기 때문에 배열[h] 값이 숫자 h+1보다 크거나 같음
    = h+1 이상의 값이 최소 h개 이상 존재
    = 위 내용을 for문과 조건으로 작성하여 해결

다른 사람의 풀이

  • 중요 로직은 같음
  • 디테일한 부분에서 불필요한 로직을 줄일수 있음
    • Arrays.sort(citations) 해서 사용하면 3줄을 1줄로 줄일 수 있다
    • if조건대신 Math.max or min을 사용하여 판단 가능

 

느낀점

  • list를 정렬하는 여러가지 방법
    • 1. Collections (java.utils 기본 적인 정렬을 사용)
    • 2. List.sort() 사용 (compare 직접 구현 = 복잡한 정렬을 사용할때)
      같으면0, 작으면 음수, 크면 양수로 return;
      => Result 클래스의 result1,result2를 a로 정렬, a값이 같다면 d값으로 정렬 (= order by a,d)
list.sort(new Comparator<SectionStatisticsResult>() {
    @Override
    public int compare(SectionStatisticsResult result1, SectionStatisticsResult result2) {
        int compareResult = result1.getAptNo().compareTo(result2.getAptNo());
        if(compareResult == 0 && result1.getDong() != null && result2.getDong() != null) compareResult = result1.getDong().compareTo(result2.getDong());
        return compareResult;
    }
});
  • 큰/작은 값을 찾을때 if가 아닌 Math.max() / Math.min() 을 사용하자
반응형

+ Recent posts