프로그래머스LV1_2

개발자를 꿈꾸는 뚱이·2026년 3월 12일

코딩테스트 스터디

목록 보기
19/39

기록

  • 제일 작은 수 제거하기
    import java.util.*;
    
    class Solution {
        public int[] solution(int[] arr) {
            if(arr.length - 1 == 0) return new int[]{-1};
            int[] answer = new int[arr.length - 1];
            int min = arr[0];
            for(int i = 1; i < arr.length; i++)
                if(min > arr[i]) min = arr[i];
            ArrayList<Integer> list = new ArrayList<>();
            for(int num : arr){
                if(num == min) continue;
                list.add(num);
            }
            for(int i = 0; i < list.size(); i++){
                answer[i] = list.get(i);
            }   
            return answer;
        }
    }
    
    // ArrayList 안쓴 풀이
    class Solution {
        public int[] solution(int[] arr) {
            if (arr.length == 1) return new int[]{-1};
            int min = arr[0];
            for (int i = 1; i < arr.length; i++) {
                if (min > arr[i]) min = arr[i];
            }
            int[] answer = new int[arr.length - 1];
            int idx = 0;
            for (int num : arr) {
                if (num == min) continue;
                answer[idx++] = num;
            }
            return answer;
        }
    }
ArrayList를 써서 풀었다가 안쓰는 방법을 생각하여 해결해보았다.
  • 내적
    class Solution {
        public int solution(int[] a, int[] b) {
            int answer = 0;
            for(int i = 0; i < a.length; i++){
                answer += a[i] * b[i];
            }
            return answer;
        }
    }
  • 수박수박수박수박수박수?
    class Solution {
        public String solution(int n) {
            StringBuilder sb = new StringBuilder();
            for(int i = 0; i < n; i++){
                if(i % 2 == 0) sb.append("수");
                else sb.append("박");
            }
            return sb.toString();
        }
    }
String에 더하는 방식이 아닌 StringBuilder를 사용하여 해결
  • 약수의 개수와 덧셈
    class Solution {
        public int solution(int left, int right) {
            int answer = 0;
            for(int i = left; i <= right; i++){
                answer = (cnt(i) % 2 == 0)? answer + i : answer - i;
            }
            return answer;
        }
        
        private int cnt(int num){
            int result = 0;
            for(int i = 1; i <= num ; i++){
                if(num % i == 0) result++;
            }
            return result;
        }
    }
    
    // 개선
    class Solution {
        public int solution(int left, int right) {
            int answer = 0;
            for(int i = left; i <= right; i++){
                if (i % Math.sqrt(i) == 0) {
                    answer -= i;
                } else {
                    answer += i;
                }
            }
            return answer;
        }
    }
처음에 반복문 안에서 해당 숫자의 약수 개수로 판단했는데 조금 느리다고 생각하여 약수 개수를 매번 구하는 것이 아니라 제곱수가 아니면 짝수인 것을 파악하여 그것을 이용하여 해결하는 방식으로 개선
  • 문자열 내림차순으로 배치하기
    import java.util.*;
    
    class Solution {
        public String solution(String s) {
            char[] ch = s.toCharArray();
            Arrays.sort(ch);
            StringBuilder sb = new StringBuilder();
            for(int i = ch.length - 1; i >= 0; i--) sb.append(ch[i]);
            return sb.toString();
        }
    }
    
    // 개선
    import java.util.*;
    
    class Solution {
        public String solution(String s) {
            char[] ch = s.toCharArray();
            Arrays.sort(ch);
            return new StringBuilder(new String(ch)).reverse().toString();
        }
    }
반복문으로 마지막에 문자열을 정리했는데 StringBuilder.reverse() 함수가 있어서 이걸 활용하면 된다.
  • 부족한 금액 계산하기
    class Solution {
        public long solution(int price, int money, int count) {
            long answer = (((long)(price * count) + price) * count / 2) - money;
            return (answer > 0)? answer : 0;
        }
    }
처음에 계산할 때 int형으로 계속 계산해서 틀렸는데 ((price count + price) count / 2)를 제한사항 최대로 보면 ((2500 2500 + 2500) 2500)을 하면 약 156억으로 int형 최대인 21억을 넘어서 long형 캐스팅이 필요하다.
  • 문자열 다루기 기본
    class Solution {
        public boolean solution(String s) {
            if(s.length() != 4 && s.length() != 6) return false;
            for(char c : s.toCharArray()){
                if(!Character.isDigit(c)) return false;
            }
            return true;
        }
    }
길이가 4와 6인지 비교 후 각 원소가 숫자인지 체크하여 해결
  • 행렬의 덧셈
    class Solution {
        public int[][] solution(int[][] arr1, int[][] arr2) {
            int[][] answer = new int[arr1.length][arr1[0].length];
            for(int i = 0; i < arr1.length; i++){
                for(int j = 0; j < arr1[i].length; j++){
                    answer[i][j] = arr1[i][j] + arr2[i][j];
                }
            }
            return answer;
        }
    }
각 행렬의 원소끼리 더하면 해결
  • 직사각형 별 찍기
    import java.util.Scanner;
    
    class Solution {
        public static void main(String[] args) {
            Scanner sc = new Scanner(System.in);
            int a = sc.nextInt();
            int b = sc.nextInt();
            for(int i = 0; i < b; i++){
                for(int j = 0; j < a; j++){
                    System.out.print("*");
                }
                System.out.println();
            }
        }
    }
  • 같은 숫자는 싫어
    import java.util.*;
    
    public class Solution {
        public int[] solution(int []arr) {
            Stack<Integer> s = new Stack<>();
            for(int num : arr){
                if(s.isEmpty() || s.peek() != num) s.push(num);
            }
            int[] answer = new int[s.size()];
            int last = answer.length - 1;
            while(!s.isEmpty()){
                answer[last--] = s.pop();
            }
            return answer;
        }
    }
이 문제로 자바에서 Stack을 사용하는 방법을 정리했다.
함수설명
기본 사용 방법Stack s = new Stack<>();
push(item)스택에 아이템을 삽입
pop()스택의 마지막 값을 제거하고 반환
peek()스택의 마지막 값을 반환(삭제 X)
isEmpty()스택이 비었는지 반환
size()스택의 크기 반환
clear()스택의 모든 원소 제거
contains(item)스택에 해당 아이템이 있는지 반환
  • 최대공약수와 최소공배수
    class Solution {
        public int[] solution(int n, int m) {
            int[] answer = new int[2];
            int a = Math.max(n, m), b = Math.min(n, m);
            while(b != 0){
                int tmp = a % b;
                a = b;
                b = tmp;
            }
            answer[0] = a;
            answer[1] = (n / a) * (m / a) * a;
            return answer;
        }
    }
최대공약수를 구해서 최소공배수를 구해야 하는데 최소공배수를 n * m / a를 하면 되는데 그러면 int형을 넘을 수 있어 풀이처럼 계산하였다.
  • 크기가 작은 부분 문자열
    import java.util.*;
    
    class Solution {
        public int solution(String t, String p) {
            int answer = 0;
            Long _p = Long.parseLong(p);
            for(int i = 0; i < t.length() - p.length() + 1; i++){
                String s = t.substring(i, i + p.length());
                if(Long.parseLong(s) <= _p) answer++;
            }
            return answer;
        }
    }
    
    // 속도 개선
    class Solution {
        public int solution(String t, String p) {
            int answer = 0;
            for(int i = 0; i <= t.length() - p.length(); i++) {
                if(t.substring(i, i + p.length()).compareTo(p) <= 0) {
                    answer++;
                }
            }
            return answer;
        }
    }
각 부분 문자열로 잘라서 자료형을 long으로 하여서 비교했는데 제출해보니까 조금 느린거 같아서 고민해보니 문자열끼리 서로 비교해도 괜찮다고 판단해서 개선해보았다.
  • 삼총사
    class Solution {
        public int solution(int[] number) {
            int answer = 0;
            for(int i = 0; i < number.length - 2; i++){
                for(int j = i + 1; j < number.length - 1; j++){
                    for(int k = j + 1; k < number.length; k++){
                        if(number[i] + number[j] + number[k] == 0) answer++;
                    }
                }
            }
            return answer;
        }
    }
for문 3중 중첩한게 좀 걸리긴 하는데 제한사항에서 배열이 짧아서 큰 무리는 없을 거 같아서 이렇게 했다.
  • 예산
    import java.util.*;
    
    class Solution {
        public int solution(int[] d, int budget) {
            int answer = 0;
            Arrays.sort(d);
            for(int i = 0; i < d.length; i++){
                if(budget < d[i]) break;
                budget -= d[i];
                answer++;
            }
            return answer;
        }
    }
정렬해서 살 수 있는 최대 개수를 세면 됨
  • 3진법 뒤집기
    class Solution {
        public int solution(int n) {
            int answer = 0;
            StringBuilder sb = new StringBuilder();
            while(n != 0){
                sb.append(Integer.toString(n % 3));
                n /= 3;
            }
            System.out.println(sb);
            long reverse = Long.parseLong(sb.toString());
            int idx = 0;
            while(reverse != 0){
                answer += (reverse % 10) * Math.pow(3, idx++);
                reverse /= 10;
            }
            return answer;
        }
    }
    
    // Integer.parseInt()의 진법을 넣어 변환
    class Solution {
        public int solution(int n) {
            StringBuilder sb = new StringBuilder();
            while(n != 0) {
                sb.append(n % 3);
                n /= 3;
            }
            return Integer.parseInt(sb.toString(), 3);
        }
    }
3진법으로 수를 바꾼 다음 long형으로 뒤집은 수를 얻어 10진법으로 다시 바꿔 해결했는데 찾아보니 Integer.parseInt()의 매개변수에 진법을 넣으면 자동으로 변환을 해주는 것이 있었다. 이건 이번에 처음 알았는데 진법 문제 나오면 활용해야겠다.(2진법부터 36진법까지 가능)
  • 이상한 문자 만들기
    class Solution {
        public String solution(String s) {
            s = s.toLowerCase();
            StringBuilder sb = new StringBuilder(s);
            int idx = 0;
            for(int i = 0; i < sb.length(); i++){
                if(sb.charAt(i) == ' ') idx = 0;
                else{
    			  if(idx % 2 == 0)
    	            	sb.setCharAt(i, Character.toUpperCase(sb.charAt(i)));
    	            idx++;
                }
            }
            return sb.toString();
        }
    }
모두 소문자 변환 후 공백 기준으로 해당 인덱스가 짝수이면 대문자로 바꾸면 해결
  • 최소직사각형
    class Solution {
        public int solution(int[][] sizes) {
            int w = 0, h = 0;
            for(int i = 0; i < sizes.length; i++){
                int _w = Math.max(sizes[i][0], sizes[i][1]);
                int _h = Math.min(sizes[i][0], sizes[i][1]);
                w = Math.max(w, _w);
                h = Math.max(h, _h);
            }
            return w * h;
        }
    }
가로와 세로 중 한쪽은 둘 중 짧은 변 중 가장 긴 변, 다른 한쪽은 둘 중 긴 변 중 가장 긴 변을 구해 곱하면 해결
  • 가장 가까운 글자
    class Solution {
        public int[] solution(String s) {
            int[] answer = new int[s.length()];
            int[] used = new int[26];
            for(int i = 0; i < s.length(); i++){
                char c = s.charAt(i);
                if(used[c - 'a'] != 0){
                    answer[i] = (i + 1) - used[c - 'a'];
                    used[c - 'a'] = i + 1;
                }
                else{
                    answer[i] = -1;
                    used[c - 'a'] = i + 1;
                }
            }
            return answer;
        }
    }
해당 인덱스를 사용했는지 체크하여 처음 사용이면 -1, 아니라면 현재 인덱스 - 이전 인덱스 값을 하고 매번 해당 사용 체크에 본인 인덱스를 넣어 해결
  • 시저 암호
    class Solution {
        public String solution(String s, int n) {
            StringBuilder sb = new StringBuilder();
            for(char c : s.toCharArray()){
                if(c == ' ') sb.append(" ");
                else{
                    int idx = c + n;
                    if((Character.isLowerCase(c) && idx > 122) || Character.isUpperCase(c) && idx > 90){
                        idx -= 26;
                    }
                    sb.append((char)idx);
                }
            }
            return sb.toString();
        }
    }
    
    class Solution {
        public String solution(String s, int n) {
            StringBuilder sb = new StringBuilder();
            for(char c : s.toCharArray()){
                if(c == ' '){
                    sb.append(c);
                }
                else{
                    char base = Character.isLowerCase(c) ? 'a' : 'A';
                    char shifted = (char) ((c - base + n) % 26 + base);
                    sb.append(shifted);
                }
            }
            return sb.toString();
        }
    }
각 인덱스의 문자가 소문자, 대문자 여부에 따라 아스키 코드 값에서 z나 Z를 넘어가면 뺴는 것으로 해서 해결했는데 아스키 코드 값을 쓰지 않고 좀 더 직관적인 방법을 찾아 개선했다.
  • 푸드 파이트 대회
    class Solution {
        public String solution(int[] food) {
            int total = 1;
            for(int i = 1; i < food.length; i++){
                total += (food[i] / 2) * 2;
            }
            char[] c = new char[total];
            c[total / 2] = '0';
            int idx = 0;
            for(int i = 1; i < food.length; i++){
                int count = food[i] / 2;
                for(int j = 0; j < count; j++){
                    c[idx] = (char)(i + '0');
                    c[c.length - 1 - idx] = (char)(i + '0');
                    idx++;
                }
            }
            return new String(c);
        }
    }
    
    // reverse로 붙이는 방식
    class Solution {
        public String solution(int[] food) {
            StringBuilder sb = new StringBuilder();
            for(int i = 1; i < food.length; i++) {
                int count = food[i] / 2;
                for(int j = 0; j < count; j++) {
                    sb.append(i);
                }
            }
            return sb.toString() + "0" + sb.reverse().toString();
        }
    }
해당 음식 개수를 보고 세팅할 총 음식 개수를 얻어 중간에 0을 넣고 나머지는 앞과 뒤를 해당 음식의 절반 만큼 배치하여 문자열로 바꾸면 해결된다. StringBuilder로 반쪽만 먼저 만들고 반대쪽은 뒤집어서 붙여 좀 더 간단하게 해결할 수 있지만 앞 선 코드가 속도면에선 더 빠름
profile
개발자가 되기 위해 열심히 춤추는 중이에요 🕺

0개의 댓글