Skip to content

Commit 21f9aa6

Browse files
authored
Merge pull request #1980 from sangyyypark/main
[sangyyypark] WEEK 01 solutions
2 parents 3ec367d + ac63034 commit 21f9aa6

File tree

5 files changed

+213
-0
lines changed

5 files changed

+213
-0
lines changed
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/**
2+
* 1 .문제 정의
3+
* 배열이 주어지면, 배열에 포함된 정수가 중복이 없다면 fasle, 적어도 1회 이상 중복이 있다면 true를 반환해야한다.
4+
* 배열의 크기는?
5+
* - 1 <= length <= 100000
6+
* 2. naive algorithm 도출
7+
* - 배열을 탐색하면서 Set자료구조에 넣는다. 이때 Set에 넣으려는 값이 이미 포함되어있는지를 확인합니다.. true를 반환.
8+
* - 배열 전체를 탐색했는데 포함여부에서 걸리지 않으면 false를 반환
9+
* 3. 시간&공간복잡도 분석
10+
* - 배열의 길이가 N이면 O(N)의 시간 복잡도
11+
* 4. 코드작성
12+
*/
13+
import java.util.*;
14+
public class sangyyypark {
15+
public boolean containsDuplicate(int[] nums) {
16+
Set<Integer> set = new HashSet<>();
17+
for(int i = 0; i < nums.length; i++) {
18+
int value = nums[i];
19+
if(set.contains(value)) {
20+
return true;
21+
}
22+
set.add(value);
23+
}
24+
return false;
25+
}
26+
}
27+

house-robber/sangyyypark.java

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/**
2+
배열은 강도가 털 집의 돈을 순서대로 나타냅니다.
3+
*
4+
* 인접한 두 집을 동시에 털면 경찰에 알림이 가기 때문에 피해야 합니다.
5+
*
6+
* 하루에 훔칠 수 있는 가장 많은 돈을 구하는 문제입니다.
7+
*
8+
*
9+
* 2. naive 알고리즘 도출
10+
*
11+
* - 현재 집을 털기 → 바로 이전 집은 못 털었으므로 prev2 + 현재집
12+
* - 현재 집을 안 털기 → 이전까지의 최댓값 유지 prev1
13+
*/
14+
class sangyyypark {
15+
public static int rob(int[] nums) {
16+
if (nums == null || nums.length == 0) {
17+
return 0;
18+
}
19+
if (nums.length == 1) {
20+
return nums[0];
21+
}
22+
23+
24+
int prev2 = 0; // i-2번째 집까지의 최대 금액
25+
int prev1 = 0; // i-1번째 집까지의 최대 금액
26+
27+
for (int num : nums) {
28+
// 현재 집을 털 경우: prev2 + num
29+
// 현재 집을 안 털 경우: prev1
30+
int current = Math.max(prev1, prev2 + num);
31+
32+
33+
prev2 = prev1;
34+
prev1 = current;
35+
}
36+
37+
return prev1;
38+
}
39+
}
40+
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
2+
import java.util.HashSet;
3+
import java.util.Set;
4+
/**
5+
각 연속 수열의 시작점에서만 카운팅하기
6+
7+
1. 모든 숫자를 Set에 넣기
8+
2. 배열을 탐색하면서 현재 index에 해당하는 숫자 -1 값이 Set에 존재하는지 확인
9+
3. 만약 Set에 값이 존재한다면 연속된 숫자의 시작지점이 아니다.
10+
4. 만약 Set에 값이 존재하지 않는다면 연속된 숫자의 시작지점이다.
11+
5. 시작지점을 찾았으면 num + 1값이 존재하는지 확인, num+2값이 존재하는지 확인하면서 등장하지 않을때 까지 체크하고 길이를 최대 길이와 비교한다. (이때 배열을 기준으로 탐색하면 배열에 중복 숫자가 있을경우 매번 중복숫자에 대해서 length를 체크해야하므로 Set이 이득임)
12+
*/
13+
class sangyyypark {
14+
public int longestConsecutive(int[] nums) {
15+
Set<Integer> set = new HashSet<>();
16+
for(int i = 0; i < nums.length; i++) {
17+
int num = nums[i];
18+
set.add(num);
19+
}
20+
int max = 0;
21+
22+
for(int num : set) {
23+
if(set.contains(num-1)) {
24+
continue;
25+
}
26+
int index = 1;
27+
int length = 1;
28+
while(set.contains(num+index)) {
29+
index++;
30+
length++;
31+
}
32+
max = Math.max(max,length);
33+
}
34+
return max;
35+
}
36+
}
37+
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import java.util.*;
2+
/**
3+
* 1 .문제 정의
4+
5+
배열이 있는데 여기서 각 숫자가 등장한 빈도수를 체크하고 K번째 까지 높은 빈도로 등장한 수를 리턴하는 문제입니다.
6+
7+
- n의 길이는 1 ~ 10000
8+
9+
* 2. naive algorithm 도출
10+
11+
배열을 순회함면서 Map에 넣으면서 빈도수를 체크.
12+
빈도수 계산이 끝나고 나면 빈도수를 기준으로 내림차순 정렬
13+
14+
*
15+
* 3. 시간&공간복잡도 분석
16+
* O(N) + O(M) + O(M log M) + O(K) = O(N + N log N) = O(N log N)
17+
18+
* 4. 코드작성
19+
*/
20+
class sangyyypark {
21+
public int[] topKFrequent(int[] nums, int k) {
22+
Map<Integer,Integer> map = new HashMap<>();
23+
for(int i = 0; i < nums.length; i++) {
24+
int num = nums[i];
25+
if(map.containsKey(num)) {
26+
map.put(num, map.get(num) + 1);
27+
}
28+
else {
29+
map.put(num,1);
30+
}
31+
}
32+
33+
List<Integer> keySet = new ArrayList<>(map.keySet());
34+
keySet.sort(new Comparator<Integer>() {
35+
@Override
36+
public int compare(Integer o1, Integer o2) {
37+
return map.get(o2).compareTo(map.get(o1));
38+
}
39+
});
40+
41+
int [] result = new int[k];
42+
int index = 0;
43+
for(int i = 0; i < k; i++) {
44+
result[index] = keySet.get(i);
45+
index++;
46+
}
47+
return result;
48+
}
49+
}
50+

two-sum/sangyyypark.java

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/**
2+
* 1 .문제 정의
3+
* 배열이 주어지면, 배열에 포함된 정수가 중복이 없다면 fasle, 적어도 1회 이상 중복이 있다면 true를 반환해야한다.
4+
* 배열의 크기는?
5+
* - 1 <= length <= 100000
6+
* 2. naive algorithm 도출
7+
* - 배열을 탐색하면서 Set자료구조에 넣는다. 이때 Set에 넣으려는 값이 이미 포함되어있는지를 확인합니다.. true를 반환.
8+
* - 배열 전체를 탐색했는데 포함여부에서 걸리지 않으면 false를 반환
9+
* 3. 시간&공간복잡도 분석
10+
* - 배열의 길이가 N이면 O(N)의 시간 복잡도
11+
* 4. 코드작성
12+
*/
13+
import java.util.*;
14+
15+
/**
16+
* 1 .문제 정의
17+
* 배열에서 동일한 숫자를 사용하지 않고 두개의 숫자를 선택해서 합이 target이 나오는지 판별해야 하는 문제
18+
* - 배열의 길이는?
19+
* - 2 <= length <= 10000 라고 가정합니다.
20+
* - target을 만드는 경우가 여러개가 있다면?
21+
* - 오직 하나의 경우만 있다고 가정합니다.
22+
* 2. naive algorithm 도출
23+
* - 투포인터 알고리즘을 사용해서 구현
24+
* - left,right를 각각 선정합니다.
25+
* - left와 right가 같으면 합을 구하지 않고 Right를 1칸 전진합니다.
26+
* - left와 right의 합을 구해서 target이 아니라면 right를 1칸 전진합니다.
27+
* - right가 마지막에 도달했는데도 target이 아니라면 left를 1칸 전진합니다.
28+
* - 위 과정을 반복합니다.
29+
* 3. 시간&공간복잡도 분석
30+
* - 투포인터 알고리즘의 시간복잡도는 O(N^2)
31+
* 4. 코드작성
32+
*/
33+
public class sangyyypark {
34+
public int[] twoSum(int[] nums, int target) {
35+
int left = 0;
36+
int right = 1;
37+
int [] answer = new int [2];
38+
while(left < nums.length && right < nums.length) {
39+
int a = nums[left];
40+
int b = nums[right];
41+
if(target == a + b) {
42+
answer[0] = left;
43+
answer[1] = right;
44+
break;
45+
}
46+
47+
48+
if(right >= nums.length -1) {
49+
left++;
50+
right = left+1;
51+
}
52+
else {
53+
right++;
54+
}
55+
}
56+
return answer;
57+
}
58+
}
59+

0 commit comments

Comments
 (0)