코드카타 ( 숫자 짝궁 )

song yuheon·2023년 8월 30일
0

Java Algorithm

목록 보기
3/18
post-thumbnail

[level 1] 숫자 짝꿍 - 131128

문제 링크

성능 요약

메모리: 74 MB, 시간: 0.69 ms

구분

코딩테스트 연습 > 연습문제

채점결과

Empty

문제 설명

두 정수 X, Y의 임의의 자리에서 공통으로 나타나는 정수 k(0 ≤ k ≤ 9)들을 이용하여 만들 수 있는 가장 큰 정수를 두 수의 짝꿍이라 합니다(단, 공통으로 나타나는 정수 중 서로 짝지을 수 있는 숫자만 사용합니다). X, Y의 짝꿍이 존재하지 않으면, 짝꿍은 -1입니다. X, Y의 짝꿍이 0으로만 구성되어 있다면, 짝꿍은 0입니다.

예를 들어, X = 3403이고 Y = 13203이라면, XY의 짝꿍은 XY에서 공통으로 나타나는 3, 0, 3으로 만들 수 있는 가장 큰 정수인 330입니다. 다른 예시로 X = 5525이고 Y = 1255이면 XY의 짝꿍은 XY에서 공통으로 나타나는 2, 5, 5로 만들 수 있는 가장 큰 정수인 552입니다(X에는 5가 3개, Y에는 5가 2개 나타나므로 남는 5 한 개는 짝 지을 수 없습니다.)
두 정수 X, Y가 주어졌을 때, X, Y의 짝꿍을 return하는 solution 함수를 완성해주세요.

제한사항
  • 3 ≤ X, Y의 길이(자릿수) ≤ 3,000,000입니다.
  • X, Y는 0으로 시작하지 않습니다.
  • X, Y의 짝꿍은 상당히 큰 정수일 수 있으므로, 문자열로 반환합니다.

입출력 예
X Y result
"100" "2345" "-1"
"100" "203045" "0"
"100" "123450" "10"
"12321" "42531" "321"
"5525" "1255" "552"

입출력 예 설명

입출력 예 #1

  • X, Y의 짝꿍은 존재하지 않습니다. 따라서 "-1"을 return합니다.

입출력 예 #2

  • X, Y의 공통된 숫자는 0으로만 구성되어 있기 때문에, 두 수의 짝꿍은 정수 0입니다. 따라서 "0"을 return합니다.

입출력 예 #3

  • X, Y의 짝꿍은 10이므로, "10"을 return합니다.

입출력 예 #4

  • X, Y의 짝꿍은 321입니다. 따라서 "321"을 return합니다.

입출력 예 #5


코드 구현


전략

  1. X, Y를 문자열 LinkedList로 만들어준다
  2. temp라는 Linked List를 만든다
  3. X를 기준으로 for문을 돌리고 X와 Y가 일치할때 temp에 해당 값을 추가하고 Y에서 그 요소를 제거한다.
  4. temp를 내림차순 정렬하고 string으로 반환한다.

1-1. 문자열을 문자로 이루어진 String 배열로 만들어야한다.
https://lktprogrammer.tistory.com/137

// 구현은 하였지만 비효율적 
List<String> xList = new LinkedList<>();
StringTokenizer xTokenizer = new StringTokenizer(X,"0123456789",true);
        while(xTokenizer.hasMoreTokens())
            temp.add(xTokenizer.nextToken());

리스트 형으로 객체 생성과 동시에 초기화로 코드 변경

// Sol Code
List<String> temp = new LinkedList<>(X.chars().mapToObj(n->String.valueOf((char)n)).collect(Collectors.toList()));
  1. temp라는 Linked List를 만든다
List<String> temp = new LinkedList<>();
  1. X를 기준으로 for문을 돌리고 X와 Y가 일치할때 temp에 해당 값을 추가하고 Y에서 그 요소를 제거한다.
for (String n:xList) {
    if(yList.contains(n)){
        temp.add(n);
        yList.remove(n);
    }
}
  1. temp를 내림차순 정렬하고 string으로 반환한다.
String answer = temp.stream().sorted((n1,n2)->n2.compareTo(n1)).collect(Collectors.joining());
if(answer.equals(""))
    return "-1";
else if (Integer.parseInt(answer)==0)
    return "0";
return answer;

코드의 속도가 너무 느려서 실패하였다.
=>


속도를 개선하긴 했지만 여전히 시간 초과로 실패하였다.

class Solution {
    public String solution(String X, String Y) {
        List<String> temp = new ArrayList<>();
        String tempChar="";

        for (char n:X.toCharArray()) {
            tempChar=String.valueOf(n);
            if (Y.contains(tempChar)) {
                temp.add(tempChar);
                Y=Y.replaceFirst(tempChar,"");
            }
        }
        temp.sort((n1,n2)->n2.compareTo(n1));
        String answer =temp.stream().collect(Collectors.joining());
        if(answer.equals(""))
            return "-1";
        else if (answer.replace("0","").isEmpty())
            return "0";
        return answer;

    }
}

여전히 안된다 ....

import java.util.LinkedList;
import java.util.stream.Collectors;
class Solution {
    public String solution(String X, String Y) {
        LinkedList<String> temp = new LinkedList<>();
        String tempChar="";

        for (int i = 0; i < X.length(); i++) {
            tempChar=X.substring(i,i+1);
            if (Y.contains(tempChar)) {
                temp.add(tempChar);
                Y=Y.replaceFirst(tempChar,"");
            }
        }
        String answer =temp.stream().sorted((n1,n2)->n2.compareTo(n1)).collect(Collectors.joining());
        if(answer.equals(""))
            return "-1";
        else if (answer.replace("0","").isEmpty())
            return "0";
        return answer;

    }
}

전략 변경


  1. hashMap을 이용해서 Y의 문자 빈도를 기록
        // 문자 빈도를 저장하기 위한 HashMap 생성
        HashMap<Character, Integer> yFreq = new HashMap<>();

        // Y 문자 빈도 HashMap 객체에 저장
        for (char ch : Y.toCharArray()) {
            yFreq.put(ch, yFreq.getOrDefault(ch, 0) + 1);
        }
  1. 우선 순위 큐로 내림차순 정렬 객체 생성
PriorityQueue<Character> priQueue = new PriorityQueue<>((a, b) -> b - a);
  1. Y에 있는 문자만 큐 객체에 생성, HashMap 객체에 해당 문자 갯수 -1 씩 반복
for (char ch : X.toCharArray()) {
    if (yFreq.getOrDefault(ch, 0) > 0) {
        priQueue.add(ch);
        yFreq.put(ch, yFreq.get(ch) - 1);
    }
}
  1. StringBuilder로 answer 문자열 생성
StringBuilder sb = new StringBuilder();
while (!priQueue.isEmpty()) {
    sb.append(priQueue.poll());
}

Trouble Shooting

  1. List.of
    List.of는 Stream을 직접 리스트로 만들수 없다
    // Trouble Code
    List<String> temp = new LinkedList<>(List.of(X.chars().mapToObj(n->String.valueOf((char)n))));
  • Sol = collect를 이용해서 리스트 형으로 만든다.
// Sol Code
List<String> temp = new LinkedList<>(X.chars().mapToObj(n->String.valueOf((char)n)).collect(Collectors.toList()));
profile
backend_Devloper

0개의 댓글