본문 바로가기

알고리즘/문자열

557. Reverse Words in a String III

출처

 

Reverse Words in a String III - LeetCode

Level up your coding skills and quickly land a job. This is the best place to expand your knowledge and get prepared for your next interview.

leetcode.com

[문제 설명]

문장을 공백으로 나눠서 역순으로 정렬한 후 return

abcd abc면 abcd -> dcba cba로 리턴하면 됨.

 

[처음 생각한 접근 방법]
1.문자 배열을 주어진 String s랑 같은 크기의 배열(char[] charArray)을 만든다.

2.s를 0부터 차례대로 돌림.
그러다가 공백이 나오면 처음 인덱스부터 공백 이전 인덱스까지 서로 위치를 바꿔서(swap메서드)
문자 배열(charArray)에 넣어줍니다.
s와 똑같은 위치에 문자 배열에도 공백을 넣어줍니다.

Let's take LeetCode contest면

시작점은 0이고,
5에서 공백이 나오니까 0~4까지 서로 swap메서드 사용.
끝나고 5는 charArray[5] = ' '해서 공백 넣어줌.
시작점은 이제 6부터 시작입니다.

 

[내가 쓴 코드]

import java.util.Arrays;

class Solution {
    public String reverseWords(String s) {
        char[] reversedString = new char[s.length()];

        int start = 0;
        int end = 0;
        for (int i = 0; i < s.length(); i++) {
            if (s.charAt(i) == ' ') {
                end = i-1;
                swap(start,end,s,reversedString);
                reversedString[i] = ' ';
                start = i+1;
            }
        }

        swap(start, s.length()-1, s, reversedString);

        return new String(reversedString);
    }

    private void swap(int start, int end,String original, char[] reversedString) {
        while (start <= end) {
            reversedString[start] = original.charAt(end);
            reversedString[end] = original.charAt(start);

            start++;
            end--;
        }
    }
}

리트코드 최다 추천 답안

public class Solution {
    public String reverseWords(String s) {
        char[] ca = s.toCharArray();
        for (int i = 0; i < ca.length; i++) {
            if (ca[i] != ' ') {   // when i is a non-space
                int j = i;
                while (j + 1 < ca.length && ca[j + 1] != ' ') { j++; } // move j to the end of the word
                reverse(ca, i, j);
                i = j;
            }
        }
        return new String(ca);
    }

    private void reverse(char[] ca, int i, int j) {
        for (; i < j; i++, j--) {
            char tmp = ca[i];
            ca[i] = ca[j];
            ca[j] = tmp;
        }
    }
}

접근 방법은 비슷한데 코드의 디테일에 차이가 상당합니다.
굳이 start, end 변수를 따로 두지 않고 반복문 내에 i를 사용하여 시작점을 잡고 j를 끝점을 잡아서 swap하는 방식으로 했습니다.
또한 공백일 때가 아닌 공백이 아닐 때, j를 증가(제 코드에선 end) 공백 이전까지 j를 증가시킵니다.
다음 j가 공백을 가르치면 swap하여 문자열을 거꾸로 섞고, i에 j를 대입하여 시작점을 초기화해줍니다.
다음에 생각해내기 좀 어려워보이지만 나중에 한 번 시도해봐야겠습니다.


맨 첫번째 줄에 저처럼 굳이 같은 크기의 문자 배열로 초기화하지않고, s에서 바로 문자배열을 만든 것도 잘한 거 같습니다.
생각해보니 저도 굳이 그런 식으로 배열을 새로 만들어둘 필요는 없었을 거 같습니다.

728x90
반응형

'알고리즘 > 문자열' 카테고리의 다른 글

1071. Greatest Common Divisor of Strings  (0) 2021.08.19
1436. Destination City  (0) 2021.07.23
14. Longest Common Prefix  (0) 2021.07.19
500. Keyboard Row  (0) 2021.07.13
3. Longest Substring Without Repeating Characters  (0) 2021.07.10