알파벳을 바꾸는 부분은 어렵지 않다.. 중요한 부분은 좌우키를 어떤 식으로 움직여서 최소한으로 움직이느냐인데..
실패했다
Line:19가 너무나 중요함
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
|
import java.util.*;
class Solution {
private static int answer;
// private static List<Integer> noAindexList;
public int solution(String name) {
answer = 0;
int len = name.length();
int min = name.length()-1;
for(int i=0; i<len; i++){
addAlphabetNum(name, i);
int next = i+1;
while(next<len && name.charAt(next)=='A') next++;
int ni = len-next;
min = Math.min (min , Math.min(2*i+ni, i+2*ni));
}
answer+=min;
// System.out.println(min);
return answer;
}
private void addAlphabetNum(String name, int i){
if(name.charAt(i)!='A'){
answer += changeAlphabet(name, i);
}
}
private int changeAlphabet(String name, int i){
return Math.min(name.charAt(i)-'A', 26-(name.charAt(i)-'A'));
}
}
|
cs |
대충 이런 그림인데 i의 범위가 0<= i < len이기 때문에
어떠한 AAA...AAA를 사이에두는
(이 A의 개수가 0인 경우도 포함 즉 A가 아닌 문자가 연속되는 것들도 ex)JEROEN
사이에 A의 공집합이 있다고 가정하는거임)
두 index인 i와 next의 모든 경우의 수를 다 찾아서 min값에 Math.min으로 비교할 수 있음
저렇게 구한 값중 2*i+ni가 더 작냐 i+2*ni가 더 작냐 비교 후 그 값은 min값의 후보군이 될 수 있음
2*i + ni의 의미 =>
0번 index에서 i번 index로 먼저 갔다 온 후에 next번 index로 가서 마무리 짓는다는 의미
조이스틱을 움직이기전 가장 처음의 index의 번호는 0번임
즉 i쪽으로 먼저 간 다음에(1*i) 다시 돌아와서(1*i) --> 총 2*i
0번 index에서 왼쪽으로 1번 꺽으면 len-1번 index임
그것을 활용해서 next까지의 최소 거리는 len-next로 ni라는 변수에 저장해줌
i + 2*ni의 의미 =>
이건 0번 index에서 i번 index로 먼저 갔다 오는 것이 아닌 next번 index를 먼저 갔다온다는 의미
Line:18~19를 정확하게 이해해야함 이게 좌우이동 최소값을 찾는 공식임..
이거 다 이해하고도 설명하기가 힘든데
문제 처음 봤으면 절대로 나올 수 없을 공식임..ㅠ
댓글단거 퍼옴
앞으로 쭉가는 경우는 처음 초기화로 하드코딩합니다. min = length. 그것보다 작은 경우를 찾는 알고리즘이 min = Math.min(min, i + length - next + Math.min(i, length - next)); 입니다. i+length-next는 '바로옆의 a들을 제외한 다른 문자들의 길이 -1' 입니다. 예를 들면 AAABBBBBBBAA 는 I=2일 경우 next = 10, length는 12 이어서 4이됩니다. 즉, B를 건너지 않고 반대로 넘어가는 경우를 고려하는 것입니다. 여기서 문제는 우리의 시작점은 인덱스 0인것에 있습니다. 우리는 i까지 갔다가 되돌아가거나 처음부터 뒤로가서 length-next까지 갔다가 다시 돌아오는 경우를 생각해야합니다. 앞의 예에서는 i=2 두칸앞으로 갔다가 돌아오느냐, 처음부터 뒤로가서 length-next = 12 - 10 = 2를 고려해야하는 것입니다. 이 경우에는 두개가 같은 값이지만 다를 수 있어서 Math.min으로 방향을 선택해주는 것입니다. 위의 댓글이 정확하지 않아서 댓글답니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
class Solution {
public int solution(String name) {
int answer = 0;
char[] chr = name.toCharArray();
int leftAndRight = name.length();
for(int i=0; i<chr.length; i++){
if(chr[i]!='A') {
int a = (int)(chr[i]-'A');
int b = 26-(int)(chr[i]-'A');
int upAndDown = (a>b)? b:a;
answer+=upAndDown;
}
int next = i+1;
while(next<chr.length && chr[next]=='A') next++;
leftAndRight = Math.min(leftAndRight,
i+(chr.length-next)+Math.min(i,chr.length-next));
}
answer+=leftAndRight;
return answer;
}
}
|
cs |
이게 그리디인데 이걸로 하면 틀림..
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
|
import java.util.*;
class Solution {
private static int answer;
private static List<Integer> noAindexList;
public int solution(String name) {
answer = 0;
noAindexList = new ArrayList<>();
int len = name.length();
for(int i=0; i<name.length(); i++){
addAlphabetNum(name, i);
}
int currIdx = 0;
while(!noAindexList.isEmpty()){
noAindexList.forEach(i-> System.out.print(i+" "));
int rightIdx = noAindexList.get(0);
int leftIdx = noAindexList.get(noAindexList.size()-1);
int rightShort = shortMoveNum(currIdx, rightIdx, len);
int leftShort = shortMoveNum(currIdx, leftIdx, len);
if(rightShort<=leftShort){
// System.out.print(" right"+rightShort);
currIdx = rightIdx;
noAindexList.remove(0);
answer+=rightShort;
}
else{
// System.out.print(" left");
currIdx = leftIdx;
noAindexList.remove(noAindexList.size()-1);
answer+=leftShort;
}
System.out.println();
}
return answer;
}
private int shortMoveNum(int a, int b, int len){
int small = Math.min(a,b);
int big = Math.max(a,b);
return Math.min(big-small, len-big+small);
}
private void addAlphabetNum(String name, int i){
if(name.charAt(i)!='A'){
answer += changeAlphabet(name, i);
noAindexList.add(i);
}
}
private int changeAlphabet(String name, int i){
return Math.min(name.charAt(i)-'A', 26-(name.charAt(i)-'A'));
}
}
|
cs |
'알고리즘 풀이 > 프로그래머스' 카테고리의 다른 글
[프로그래머스][JAVA] 예상 대진표 (시뮬레이션..?) (0) | 2022.03.25 |
---|---|
[프로그래머스][JAVA] 게임 맵 최단거리 (BFS(o), DFS(x)) (0) | 2022.03.25 |
[프로그래머스][JAVA] 소수 찾기 (완전 탐색, 소수) (0) | 2022.03.25 |
[프로그래머스][JAVA] 가장 큰 수 (문자열, 정렬) (0) | 2022.03.24 |
1 ★★★ [프로그래머스][JAVA] 전화번호 목록 (문자열) (0) | 2022.03.24 |