1️⃣ 컨트롤 제트
문제 설명
숫자와 "Z"가 공백으로 구분되어 담긴 문자열이 주어집니다. 문자열에 있는 숫자를 차례대로 더하려고 합니다. 이 때 "Z"가 나오면 바로 전에 더했던 숫자를 뺀다는 뜻입니다. 숫자와 "Z"로 이루어진 문자열 s가 주어질 때, 머쓱이가 구한 값을 return 하도록 solution 함수를 완성해보세요.
제한사항
- 1 ≤ s의 길이 ≤ 200
- -1,000 < s의 원소 중 숫자 < 1,000
- s는 숫자, "Z", 공백으로 이루어져 있습니다.
- s에 있는 숫자와 "Z"는 서로 공백으로 구분됩니다.
- 연속된 공백은 주어지지 않습니다.
- 0을 제외하고는 0으로 시작하는 숫자는 없습니다.
- s는 "Z"로 시작하지 않습니다.
- s의 시작과 끝에는 공백이 없습니다.
- "Z"가 연속해서 나오는 경우는 없습니다.
입출력 예
S | result |
"1 2 Z 3" | 4 |
"10 20 30 40" | 100 |
"10 Z 20 Z 1" | 1 |
"10 Z 20 Z" | 0 |
"-1 -2 -3 Z" | -3 |
입출력 예 #1
- 본문과 동일합니다.
입출력 예 #2
- 10 + 20 + 30 + 40 = 100을 return 합니다.
입출력 예 #3
- "10 Z 20 Z 1"에서 10 다음 Z, 20 다음 Z로 10, 20이 지워지고 1만 더하여 1을 return 합니다.
입출력 예 #4, #5
- 설명 생략
💻 나의 풀이
class Solution {
public int solution(String s) {
int answer = 0;
String[] sz = s.split(" "); // 공백을 기준으로 구분되는 문자열 배열 sz
for(int i=0; i<sz.length; i++){ // sz 길이 만큼 반복
if(sz[i].equals("Z")){ // sz 배열의 i번째 원소가 Z 라면
answer -= Integer.parseInt(sz[i-1]); //합에서 i-1번째의 원소를 정수로 변환시켜 뺀다.
continue; // 다음 번째 원소를 진행
}
answer += Integer.parseInt(sz[i]); // Z가 아닐 경우 합함
}
return answer;
}
}
먼저 공백을 기준으로 구분되는 문자열 배열인 sz를 만들어줍니다.
sz배열 길이만큼 반복하면서 sz의 원소들을 Integer.parseInt를 통해 차례대로 합해줍니다.
그리고 그 사이에 if문을 사용해서 sz의 i번째 원소가 Z와 같다면 answer엥서 i-1번째의 원소를 정수로 변환시켜 빼주도록 합니다. continue도 잊지 않고 넣어줘서 다음 번째 원소를 이어서 계속 합하도록 해줘야하는거 주의해야합니다! 저는 처음에 continue를 미처 생각못해서 통과가 안됐습니다.. 😂
🔎 다른 사람의 풀이
import java.util.*;
class Solution {
public int solution(String s) {
int answer = 0;
Stack<Integer> stack = new Stack<>();
for (String w : s.split(" ")) {
if (w.equals("Z")) {
stack.pop();
} else {
stack.push(Integer.parseInt(w));
}
}
for (int i : stack) {
answer += i;
}
return answer;
}
}
stack을 사용하기 너무 좋은 문제라고 하네요. 다들 stack을 사용하심. 얼마전에 자바의 정석으로 컬렉션 부분을 분명 복습했는데도 저는 왜... stack 생각을 못했을까요ㅠㅠ 역시 강의를 보고 들어도 직접 써보는 것이 중요하다는 생각이 들었습니다. 안쓰다보니 생각 자체가 안떠오르네요.
코드를 좀 더 자세히 분석해보겠습니다.
for (String w : s.split(" ")) { → 문자열을 공백을 기준으로 분리하고 각 단어에 대해 처리
if (w.equals("Z")) { stack.pop(); } → "Z"인 경우, 스택에서 맨 위의 요소를 팝하여 제거
else { stack.push(Integer.parseInt(w)); } → "Z"가 아닌 경우, 단어를 정수로 변환하여 스택에 푸시
for (int i : stack) { answer += i; } → 스택에 남아 있는 모든 요소를 더하여 결과 계산
2️⃣ 배열 원소의 길이
문제 설명
문자열 배열 strlist가 매개변수로 주어집니다. strlist 각 원소의 길이를 담은 배열을 retrun하도록 solution 함수를 완성해주세요.
제한사항
- 1 ≤ strlist 원소의 길이 ≤ 100
- strlist는 알파벳 소문자, 대문자, 특수문자로 구성되어 있습니다.
입출력 예
strlist | result |
["We", "are", "the", "world!"] | [2, 3, 3, 6] |
["I", "Love", "Programmers."] | [1, 4, 12] |
입출력 예 #1
- ["We", "are", "the", "world!"]의 각 원소의 길이인 [2, 3, 3, 6]을 return합니다.
입출력 예 #2
- ["I", "Love", "Programmers."]의 각 원소의 길이인 [1, 4, 12]을 return합니다.
💻 나의 풀이
class Solution {
public int[] solution(String[] strlist) {
// strlist배열의 길이만큼 정수 배열을 생성
int[] answer = new int[strlist.length];
for(int i=0; i<answer.length; i++){
answer[i] = strlist[i].length(); // 각 문자열의 길이를 정수 배열에 저장
}
return answer;
}
}
먼저 strlist 배열의 길이만큼 정수 배열을 생성해줍니다.
그리고 for문을 통해 각 문자열의 길이를 정수 배열에 저장해주어서 해결했습니다.
3️⃣ 중복된 문자 제거
문제 설명
문자열 my_string이 매개변수로 주어집니다. my_string에서 중복된 문자를 제거하고 하나의 문자만 남긴 문자열을 return하도록 solution 함수를 완성해주세요.
제한사항
- 1 ≤ my_string ≤ 110
- my_string은 대문자, 소문자, 공백으로 구성되어 있습니다.
- 대문자와 소문자를 구분합니다.
- 공백(" ")도 하나의 문자로 구분합니다.
- 중복된 문자 중 가장 앞에 있는 문자를 남깁니다.
입출력 예
my_string | result |
"people" | "peol" |
"We are the world" | "We arthwold" |
입출력 예 #1
- "people"에서 중복된 문자 "p"와 "e"을 제거한 "peol"을 return합니다.
입출력 예 #2
- "We are the world"에서 중복된 문자 "e", " ", "r" 들을 제거한 "We arthwold"을 return합니다.
💻 나의 풀이
class Solution {
public String solution(String my_string) {
StringBuilder answer = new StringBuilder();
for (char c : my_string.toCharArray()) {
if (answer.indexOf(String.valueOf(c)) == -1) {
answer.append(c);
}
}
return answer.toString();
}
}
toCharArray() 메소드를 사용해서 문자열을 문자 배열 char[]로 변환해줬습니다. 즉, 문자열을 구성하는 각 문자를 배열에 저장해서 반환됩니다.
그 후에 반복문을 통해 문자열을 순회하면서 현재 문자가 결과 문자열에 이미 존재하는지 확인하고, 존재하지 않을 경우 문자열에 추가해줍니다. 이렇게 하면 결과 문자열에는 중복된 문자가 없게 됩니다.
🔎 다른 사람의 풀이
import java.util.stream.Collectors;
class Solution {
public String solution(String my_string) {
return my_string.chars()
.mapToObj(Character::toString)
.distinct()
.collect(Collectors.joining());
}
}
import java.util.*;
class Solution {
public String solution(String my_string) {
String[] answer = my_string.split("");
Set<String> set = new LinkedHashSet<String>(Arrays.asList(answer));
return String.join("", set);
}
}
중복되지 않는 set의 특성을 활용한 풀이가 인상 깊었습니다.
my_string.split("") → 입력 문자열 my_string을 한 글자씩 분리하여 배열로 변환합니다. 이때 빈 문자열을 구분자로 사용하여 각 문자를 분리합니다.
new LinkedHashSet<String>(Arrays.asList(answer)) → LinkedHashSet은 입력된 순서를 유지하면서 중복된 요소를 허용하지 않습니다. 따라서 중복된 문자가 제거된 순서가 유지된 Set이 생성됩니다.
String.join("", set) → set에 있는 문자열을 빈 문자열("")을 구분자로 사용하여 결합하여 반환합니다.
💡 LinkedHashSet
Java에서 제공하는 컬렉션 중 하나로, 중복된 요소를 허용하지 않으면서 입력된 순서를 유지하는 특징을 가지고 있습니다. 이 클래스는 HashSet의 서브클래스이며, HashSet에서는 요소들의 순서가 유지되지 않지만 LinkedHashSet에서는 요소들의 입력 순서가 유지됩니다.
주요 특징은 다음과 같습니다:
- 중복된 요소 제거: LinkedHashSet은 중복된 요소를 허용하지 않습니다. 동일한 요소를 중복해서 추가하더라도 한 번만 저장됩니다.
- 순서 유지: 요소가 추가된 순서대로 반복되는 순서를 제공합니다. 이는 입력된 순서를 기억하고 있어서 요소가 추가된 순서대로 반복할 수 있습니다.
따라서 두 경우에 유용하게 활용됩니다.
- 중복을 허용하지 않는 컬렉션을 사용하고자 할 때
- 요소의 입력 순서를 유지하며 반복할 필요가 있을 때
class Solution {
public String solution(String my_string) {
String answer = "";
for(int i=0; i<my_string.length(); i++){
//my_string.indexOf(my_string.charAt(i));
if(i==my_string.indexOf(my_string.charAt(i)))
answer+=my_string.charAt(i);
}
return answer;
}
}
처음에 구현해보려고 하던 방식입니다.
이 방식은 각 문자의 첫 번째 등장 위치를 확인하여 중복을 제거하는 아이디어를 사용하고 있습니다. 그러나 이 방식은 문자열이 커질수록 성능이 떨어질 수 있습니다. 특히 indexOf 메서드는 최악의 경우에 선형 시간(O(n))이 걸릴 수 있기 때문입니다.
그래서 성능면에서는 두번째 코드가 더 좋을 것 같습니다.
4️⃣ 삼각형의 완성조건 (1)
문제 설명
선분 세 개로 삼각형을 만들기 위해서는 다음과 같은 조건을 만족해야 합니다.
- 가장 긴 변의 길이는 다른 두 변의 길이의 합보다 작아야 합니다.
삼각형의 세 변의 길이가 담긴 배열 sides이 매개변수로 주어집니다. 세 변으로 삼각형을 만들 수 있다면 1, 만들 수 없다면 2를 return하도록 solution 함수를 완성해주세요.
제한사항
- sides의 원소는 자연수입니다.
- sides의 길이는 3입니다.
- 1 ≤ sides의 원소 ≤ 1,000
입출력 예
n | result |
[1, 2, 3] | 2 |
[3, 6, 2] | 2 |
[199, 72, 222] | 1 |
입출력 예 #1
- 가장 큰 변인 3이 나머지 두 변의 합 3과 같으므로 삼각형을 완성할 수 없습니다. 따라서 2를 return합니다.
입출력 예 #2
- 가장 큰 변인 6이 나머지 두 변의 합 5보다 크므로 삼각형을 완성할 수 없습니다. 따라서 2를 return합니다.
입출력 예 #3
- 가장 큰 변인 222가 나머지 두 변의 합 271보다 작으므로 삼각형을 완성할 수 있습니다. 따라서 1을 return합니다.
💻 나의 풀이
import java.util.Arrays;
class Solution {
public int solution(int[] sides) {
Arrays.sort(sides);
if(sides[0] + sides[1] <= sides[2]){
return 2;
}
return 1;
}
}
마지막 문제는 쉽게 해결했습니다.
일단 sort로 세 변의 길이를 오름차순으로 정렬하면 가장 긴 변의 길이가 제일 마지막 인덱스 위치에 있겠죠. 삼각형이니 sides[2]가 되겠습니다.
그 다음 if문을 사용해 나머지 두변을 합한 값이 마지막 값보다 작거나 같으면 2를 리턴해주는 상황을 만들어주면 해결됩니다.
🔎 다른 사람의 풀이
import java.util.Arrays;
class Solution {
public int solution(int[] sides) {
int answer = 0;
Arrays.sort(sides);
return sides[2] >= sides[0]+sides[1] ? 2 : 1;
}
}
같은 방식인데 삼항연산자를 사용하면 이렇게 더 깔끔해지네요!
'프로그래머스 > 0단계' 카테고리의 다른 글
DAY15 문자열, 해시, 배열, 수학 (1) | 2023.12.02 |
---|---|
DAY14 조건문, 반복문, 시뮬레이션, 문자열 (0) | 2023.12.01 |
DAY12 문자열, 정렬, 사칙연산, 수학 (1) | 2023.11.29 |
DAY11 수학, 반복문 (1) | 2023.11.27 |
DAY10 조건문, 배열, 수학, 시뮬레이션 (0) | 2023.11.26 |