250821
코테
- 다단계 칫솔판매 ok
- [PCCP 기출문제] 3번 / 충돌위험 찾기
쉬운거
- 콜라츠 추측 ok
- 핸드폰 번호 가리기 ok
- 가운데 글자 가져오기 ok
- 나누어 떨어지는 숫자 배열 ok
- 수 내림차순으로 배치하기 ok
- 서울에서 김서방 찾기 ok
- 핸드폰 번호 가리기 ok
- 제일 작은 수 제거하기 ok
- 내적 ok
- 수박수박수박수박수박수? ok
- 약수의 개수와 덧셈 ok
- 부족한 금액 계산하기 ok
- 문자열 내림차순으로 배치하기 ok -
- 문자열 다루기 기본 ok
수 내림차순으로 배치하기
import java.util.Arrays;
class Solution {
public long solution(long n) {
StringBuilder sb = new StringBuilder();
// 숫자 → 문자열 → char 배열
char[] numArray = Long.toString(n).toCharArray();
// 오름차순 정렬
Arrays.sort(numArray);
// 뒤에서부터 내림차순으로 붙이기
for (int i = numArray.length - 1; i >= 0; i--) {
sb.append(numArray[i]);
}
// 다시 long 타입으로 변환
return Long.parseLong(sb.toString());
}
}
나누어 떨어지는 숫자 배열
import java.util.*;
class Solution {
public int[] solution(int[] arr, int divisor) {
List<Integer> numList = new ArrayList<>();
for (int i = 0; i < arr.length; i++) {
if (arr[i] % divisor == 0) {
numList.add(arr[i]);
}
}
if (numList.isEmpty()) {
return new int[]{-1};
}
Collections.sort(numList);
return numList.stream().mapToInt(Integer::intValue).toArray();
}
}
서울에서 김서방 찾기
class Solution {
public String solution(String[] seoul) {
int idx = 0;
for (int i = 0; i < seoul.length; i++) {
if (seoul[i].equals("Kim")) {
idx = i;
break; // 김서방 찾으면 뒤에는 더 볼 필요 없음
}
}
// 포매팅
return String.format("김서방은 %d에 있다", idx);
}
}
import java.util.Arrays;
class Solution {
public String solution(String[] seoul) {
int idx = Arrays.asList(seoul).indexOf("Kim");
return String.format("김서방은 %d에 있다", idx);
}
}
Arrays.asList(배열명).indexOf("찾는문자열") 하면 한줄이구나... 이걸 스트림으로 하면
import java.util.stream.IntStream;
class Solution {
public String solution(String[] seoul) {
// 0부터 seoul.length-1까지 인덱스 스트림 생성
int idx = IntStream.range(0, seoul.length)
.filter(i -> "Kim".equals(seoul[i]))
.findFirst() // 첫 번째 일치 인덱스
.orElse(-1); // 없으면 -1 반환 (안 나올 경우 대비)
return String.format("김서방은 %d에 있다", idx);
}
}
핸드폰 번호 가리기
이건 처음에 replace 메서드를 인덱스 범위로 잡아서 치환하려고 함
하지만 자바 String 클래스의 replace 메서드는 범위나 인덱스를 지정해서 치환하는 건 불가능하고,
해당 문자나 문자열만 특정 문자로 치환 가능
String.replace(char oldChar, char newChar); // 문자 치환
String.replace(CharSequence target, CharSequence replacement); // 문자열 단위 치환
즉 '0번~ 끝-4번 인덱스까지' *로 바꾸고 마지막 4자리는 그대로 같은 범위 치환은 직접 구현할 수 없음
대신
1. substring + StringBuilder
class Solution {
public String solution(String phone_number) {
int len = phone_number.length();
StringBuilder sb = new StringBuilder();
// 앞의 (len - 4)자리까지 *로 채우기
for (int i = 0; i < len - 4; i++) {
sb.append("*");
}
// 뒤 4자리는 그대로 붙이기
sb.append(phone_number.substring(len - 4));
return sb.toString();
}
}
2. 정규식 + replaceAll (범위 치환)
class Solution {
public String solution(String phone_number) {
return phone_number.replaceAll("\\d(?=\\d{4})", "*");
}
}
- \\d
- 숫자 한자리
- [0-9]랑 동일
- 예: "123"에서 \\d는 '1', '2', '3' 각각 매치됨
- (?=...) positive lookahead 긍정적 전방 탐색
- 앞 쪽에 특정 패턴이 있는지 확인만 하고, 실제로 매치에는 포함하지 않음
- 예:"a1b2c3"에서 "\\d(?=b)"
- '1' 다음이 'b'라서 '1'만 매치됨
- '2', '3'은 매치 안 됨
- \\d{4}
- 숫자 4자리 연속을 의미한다
- 예: "1234" 전체와 매치됨
- {n}은 반복 횟수
- \\d(?=\\d{4}) 합쳐서 보면
- "뒤에 4자리 숫자가 있는 숫자 한 자리"
- '0' 뒤에 4자리 숫자가 있나? → 맞으면 매치 → *로 변환
- '1' 뒤에 4자리 숫자가 있나? → 맞으면 매치 → *로 변환
- 마지막 4자리는 뒤에 4자리 숫자가 없으므로 매치 안 됨 → 그대로
- "뒤에 4자리 숫자가 있는 숫자 한 자리"
제일 작은 수 제거하기
import java.util.*;
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 (arr[i] < min) {
min = arr[i];
}
}
int[] answer = new int[arr.length - 1];
int idx = 0;
for (int i = 0; i < arr.length; i++) {
if (arr[i] != min) {
answer[idx++] = arr[i];
}
}
return answer;
}
}
import java.util.*;
class Solution {
public int[] solution(int[] arr) {
if (arr.length == 1) {
return new int[]{-1};
}
// 배열에서 가장 작은 수를 min에 저장
int min = Arrays.stream(arr) // 배열을 스트림으로 바꾸기
.min() // min으로 최소값 구하기
.getAsInt(); // OptionalInt 타입으로 나옴. getAsInt()로 실제 최소값 꺼내기
return Arrays.stream(arr)
.filter(n -> n != min)
.toArray();
}
}
콜라츠 추측
class Solution {
public int solution(int num) {
int cnt = 0;
while(cnt < 500) {
if (num % 2 == 0) {
num = num/2;
cnt++;
} else if (num % 2 == 1) {
num = num *3 + 1;
cnt++;
}
if (num == 1) {
return cnt;
}
}
return -1;
}
}
시간초과 나는 이유
- int 오버플로우 위험
- num * 3 + 1 하면 int 범위 넘어갈 수 있다. (int는 약 21억까지만 가능)
- 그래서 long을 써야 안전하다
- 불필요한 연산
- if (num % 2 == 0) → else 로 충분한데 else if 로 조건을 다시 검사하고 있다.
- 자바에서 % 연산은 나름 무겁기 때문에 조금이라도 줄이는 게 좋다.
class Solution {
public int solution(int num) {
long n = num;
int cnt = 0;
while(n != 1 && cnt < 500) {
if (n % 2 == 0) {
n = n/2;
} else {
n = n *3 + 1;
}
cnt++;
}
return (n == 1) ? cnt : -1;
}
}
수정내용
- cnt++ if문 밖으로 뺌
- 삼항 연산자로 처리
- while문 조건 n이 1이 아니면서 cnt가 500보다 작을 때
시간 초과 원인이 int 오버 플로우 때문이다
else는 사실상 성능 영향 거의 없다 (가독성 문제)
오버플로우가 일어나면 음수나 엉뚱한 값이 되고, 결국 1에 도달하지 못해 무한루프 비슷하게 된다.
그럼 while(cnt < 500) 때문에 계속 500번 반복하고 모든 테스트케이스에서 불필요한 연산이 이루어짐...
그래서 long을 써야 정상적으로 수렴 여부 체크 가능...
약수의 개수와 덧셈
class Solution {
public int solution(int left, int right) {
int answer = 0;
for (int i = left; i <= right; i++) {
int cnt = 0; // 위치 중요 for문 바깥이면 i 초기화 안됨
for (int j = 1; j <= i; j++) {
if (i % j == 0) {
cnt++;
}
}
if (cnt % 2 == 0) {
answer += i;
} else {
answer -= i;
}
}
return answer;
}
}
문자열 내림차순으로 배치하기
import java.util.*;
class Solution {
public String solution(String s) {
char[] str = s.toCharArray();
Arrays.sort(str);
// 내림차순으로 뒤집기
for (int i = 0; i < str.length / 2; i++) {
char temp = str[i];
str[i] = str[str.length - 1 - i];
str[str.length - 1 - i] = temp;
}
return new String(str); // str.toString(); x
}
}
스트림
import java.util.*;
class Solution {
public String solution(String s) {
return s.chars() // IntStream
.mapToObj(c -> (char)c)
.sorted(Comparator.reverseOrder())
.collect(StringBuilder::new, StringBuilder::append, StringBuilder::append)
.toString();
}
}
배열 뒤집기 없이
import java.util.*;
class Solution {
public String solution(String s) {
char[] str = s.toCharArray();
// 내림차순 정렬: 오름차순 후 Comparator 사용 없이 바로 정렬
// Integer로 변환 후 내림차순 정렬
Character[] chars = new Character[str.length];
for (int i = 0; i < str.length; i++) chars[i] = str[i];
Arrays.sort(chars, Collections.reverseOrder());
StringBuilder sb = new StringBuilder();
for (char c : chars) sb.append(c);
return sb.toString();
}
}
문자열 다루기 기본
class Solution {
public boolean solution(String s) {
// 길이가 4 또는 6이 아니면 false
if (s.length() != 4 && s.length() != 6) {
return false;
}
// 숫자인지 확인
for (int i = 0; i < s.length(); i++) {
if (!Character.isDigit(s.charAt(i))) {
return false;
}
}
return true;
}
}
농협 KT, 웹하드 ok
슬리퍼 세탁
속눈썹펌 예약
피그먼트 반품 - 뷔스티에
PC 워런티 기간 업데이트 확인 ok
내꺼 테디테일즈 레나베어 키링 상어 옷 ok