LeetCode 문제 중 난이도 Easy인 Length of Last Word이다. 문제 링크는 포스팅의 맨 마지막에 추가하였다. 언어는 Java를 사용했다.





  문제해석


알파벳 대/소문자 그리고 공백문자로 이루어진 String s에서 마지막 단어의 길이를 구하여라.

마지막단어가 존재하지 않으면 0을 리턴한다. 단어의 정의는 공백없이 이루어진 문자열을 말한다.



Example : "Hello World"가 Input이라면 World의 글자수인 5 출력





간단한 경우부터 생각해보자.

문자열을 뒤에서부터 읽다가 s.charAt(i)에서 공백문자를 발견하면 전체 문자열의 길이에서 i+1을 빼서 공백 뒤의 문자의 개수를 구한다. 만약에 공백이 아예 존재하지 않아 for문이 끝날때까지 리턴이 발생하지 않는다면 하나의 단어로 이루어진 문자열이므로 그냥 문자열의 길이를 반환하면 된다.


1
2
3
4
5
6
7
8
9
10
11
class Solution {
    public int lengthOfLastWord(String s) {
 
        for(int i=s.length()-1 ; i>=0 ; i--){
            if(s.charAt(i)==' '){
                return s.length()-i-1;
            }
        }        
        return s.length();
    }
}
cs


* charAt(int index)는 문자열에서 해당 인덱스의 문자를 반환한다. 인덱스는 0부터 시작한다.





만약 문자열의 마지막 문자가 공백문자라면 어떨까? 위의 코드대로라면 "I am a Genius   "의 반환값은 0이 된다. 우리가 얻어야 할 값은 6이다. 이 문제를 해결하기 위해 공백문자를 만났을 경우 그 뒤에 알파벳이 있었는지 확인하고 나서 리턴을 하도록 코드를 바꿔 보자.

"I am a Genius   "라는 문자열을 알파벳을 만나기 전까지 거꾸로 읽다가 s를 만나면 hasChar를 true로 바꾼 뒤 알파벳의 개수가 늘어날 때마다 count를 늘려 준다. 그러다가 또 다시 공백문자를 만나면 그 때 count 값을 반환한다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class Solution {
    public int lengthOfLastWord(String s) {
        int count=0;
        
        //알파벳이 있었는지 확인하기위한 값
        boolean hasChar=false;
        
        //뒤에서부터 세서 알파벳이 나오고 또 공백문자 나오면 count리턴
        for(int i=s.length()-1 ; i>=0 ; i--){
            if(s.charAt(i)!=' '){
                hasChar=true;
                count++;
            }else{
                if(hasChar){
                    return count;
                }
            }
        }
        
        return count;
    }
}
cs


for문 내에서 리턴이 발생하는 경우는 hasChar가 true인 상태에서 공백문자를 만났을 때이다. 문자열의 맨 앞까지 전부 읽었는데도 리턴이 발생하지 앖는 경우는 두가지이다. 문자열 전체가 공백문자로 이루어졌거나, 문자열 전체가 한 단어 여서 공백문자가 없을 때이다. 그럴 때는 count를 리턴하면 된다. 전자라면 count가 처음에 선언한 그대로 0일 것이고 후자라면 count가 문자열의 길이와 같게 된다.





Worst Case는 문자열 전체가 공백이거나, 공백이 없는 문자열일 경우 전체 문자열을 읽어야 하므로 시간복잡도는 O(n)이고 추가적인 공간을 사용하지 않으므로 공간복잡도는 O(1)이다.


2019/02/25 - [프로그래밍문제풀기] - 빅오표기법(Big O notation)





다른 해결법도 있다. 문자열을 split()함수를 이용하여 공백문자를 기준으로 잘라 배열에 넣고 배열의 마지막 요소의 길이를 구하면 된다. 전체가 하나의 문자열이거나 전부 공백문자로 이루어진 경우에 대한 예외처리를 해 준다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Solution {
    public int lengthOfLastWord(String s) {
 
        //공백문자열이 없다면 전체 문자열의 길이를 반환
        if (!s.contains(" ")) return s.length();
        
        String [] ss = s.split(" ");
 
        //공백문자로만 이루어져있다면 0 반환
        if (ss.length == 0return 0;
        
        //마지막 문자열의 길이 반환
        return ss[ss.length-1].length();
    }
}
cs


두번째 방법은 코드 단 4줄로 구현이 가능하다! 대신 새로운 배열을 위한 추가적인 메모리를 필요로 하므로 공간복잡도가 O(n)으로 늘어나게 된다.



문제 출처 링크 - https://leetcode.com/problems/length-of-last-word



LeetCode 문제 중 난이도 Easy인 Plus One이다. 문제 링크는 포스팅의 맨 마지막에 추가하였다. 언어는 Java를 사용했다.

  문제해석

비어있지 않은 배열의 숫자들이 음수가 아닌 정수를 나타낸다고 하자. 그 정수에 1을 더하여라.

가장 큰 수부터 저장되고(앞에서부터 읽으면 된다는 뜻) 배열의 각 요소들은 한 자리의 숫자들을 가지고 있다.
정수는 값이 0일 경우를 제외하고 0으로 시작하지 않는다고 가정한다.

Example 1 : 정수 123에 1을 더하면 124이므로 [1,2,4] 출력
Example 2 : 정수 4321에 1을 더하면 4322이므로 [4,3,2,2] 출력






이 문제를 어떻게 해결할까? 먼저 Example 1과 2의 예시처럼 가장 간단한 경우의 수를 생각해보자.

배열의 맨 마지막 숫자에 +1을 해 주면 간단하게 해결 될 것이다.


1
2
3
4
5
6
7
8
9
class Solution {
    public int[] plusOne(int[] digits) {
        
        int len = digits.length;
        digits[len-1]=digits[len-1]+1;
 
        return digits;
    }
}
                    Colored by Color Scripter


** 배열(뿐만 아니라 어떤 자료형을 사용하든지간에)값이 null인지 확인하는 예외처리는 가장 기본이지만 이 문제에서는 배열이 비어있지 않다고 했으므로 파라미터로 넘어오는 digits 배열이 null이거나 배열의 length가 0인 경우에 대한 예외처리는 생략한다.




배열의 마지막 숫자가 9일 땐 어떨까? 위의 코드대로라면 Input값이 [5,3,9]일 경우 Output으로 [5,4,0]대신[5,3,10]이 나온다. 각 배열의 요소는 한 자리의 숫자로 이루어져야 하므로 위의 코드에서 배열의 값이 10 이상일 경우 자리수를 하나씩 올려주는 carry()함수를 추가하고 for문을 이용해 배열을 뒤에서부터 탐색하여 자리수를 올려준다.


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
class Solution {
    public int[] plusOne(int[] digits) {
        
        int len = digits.length;
        digits[len-1]=digits[len-1]+1//배열의 마지막 값에 1을더함
 
        //그 값이 10보다 작으면(자리수가 안바뀌면) 그냥 그대로 리턴
        if(digits[len-1]<10){    
            return digits;
        }
 
        //10이상이면(9보다크면) 하나씩 올림한다
        for(int i=len-1 ; i>0 ; i--){
            if(digits[i]>9){
                carry(i,digits);
            }
        }
 
        return digits;
    }
    
    public void carry(int index,int[] digits){
        digits[index]=0;
        digits[index-1]=digits[index-1]+1;
    }
}


carry(index,digits)는 인덱스와 배열 자체를 파라미터로 받아 배열의 해당 인덱스 값이 10 이상일 경우 그 값을 0으로 만들고 배열의 인덱스-1 값에 +1을 해준다. 이 때 digits[0]이 10인 경우에는 digits[-1]가 존재하지 않으므로 digits[1]인 경우 까지만 체크하고 일단 넘어간다.





자리수를 올려주는 부분은 초등학교 때 배운 받아올림이 있는 덧셈을 생각하면 된다.








이제 거의 다 왔다! 위에서는 배열의 요소가 전부 9인 경우는 고려하지 않았다. 만일 배열의 모든 요소가 9인 경우, for문을 돌고 난 뒤 배열의 상태는 [10,0,······] 일 것이다. digits[0]에서는 더 이상 앞으로 올림해 줄 수가 없으므로 이 경우에는 배열의 크기를 1 늘리고 [1,0,0,······]으로 채워주어야 한다. 


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
class Solution {
    public int[] plusOne(int[] digits) {
        
        int len = digits.length;
        digits[len-1]=digits[len-1]+1//일단 배열의 마지막 값에 1을 더함
 
        //10보다작으면(자리수가 안바뀌면) 그냥 그대로 리턴
        if(digits[len-1]<10){    
            return digits;
        }

        //10이상이면(9보다크면) 하나씩 올림한다
        for(int i=len-1 ; i>0 ; i--){
            if(digits[i]>9){
                carry(i,digits);
            }
        }

        //배열의맨앞숫자가 10이면 배열의 크기를 1 늘리고 1000...으로 채워준다
        if(digits[0]>9){
            int[] newDigits = new int[len+1];
            newDigits[0]=1;
            for(int i=1 ; i<newDigits.length ; i++){
                newDigits[i]=0;
            }
            return newDigits;
        }
        return digits;
    }
    
    public void carry(int index,int[] digits){
        digits[index]=0;
        digits[index-1]=digits[index-1]+1;
    }
}






자 이제 완성된 코드를 돌려 보자!

Worst case는 배열의 모든 요소가 9일 경우 이므로 이 때 시간복잡도는 O(n), 공간복잡도도 O(n)이다.




2019/02/25 - [프로그래밍문제풀기] - 빅오표기법(Big O notation)



문제 출처 링크 - https://leetcode.com/problems/plus-one




Java 통합개발환경(Integrated Development Environment)을 지원해주는 인텔리제이(IntelliJ)를 설치해보도록 하자.



https://www.jetbrains.com/idea/download 에서 받으면 된다.






유료버전인 Ultimate Edition과 무료버전인 Community Edition 두가지가 있는데 당연히 유료버전이 언어도 다양하고 무료버전에서 지원되지 않는 기능들도 지원해준다. 학생이라면 무료로 1년간 Ultimate 버전을 이용할 수 있지만 모든 사람에게 가능한 옵션은 아니니 Community Edition기준으로 설명하겠다. 그리고 무료 버전도기본적으로 Java의 핵심 기능과 Mave, Gradle, Git등은 지원되기 때문에 Community 버전도 나쁘지 않다.






다운로드 완료 후 설치파일을 실행시킨다. 딱히 어려운 점은 없다. 그냥 Next버튼만 계속 누르면 된다.





설치 완료후 Run IntelliJ IDEA Community Edition에 체크하고 Finish를 누르면 인텔리제이가 실행된다.






설치후 IntelliJ를 처음 실행시키면 import할 환경설정이 있는지 물어본다. 처음 설치시에는 아래의 Do not import settings를 선택하면 되고, 전에 쓰던 환경설정을 Export한 파일이 있다면 해당 파일을 선택한다.





UI 테마를 고르는 화면이고 Darcula가 인기가 많다. 사실 맨처음 저 단어를 봤을때 드라큘라인줄 알았다...(TMI) 

어쨌든 이런건 나중에 바꿀 수 있으니 고민하지말고 아무거나 고른 뒤 넘어가자.





IntelliJ가 정상적으로 설치되었다! 여기까지 온 김에 HelloWorld까지 찍어보도록 하자. Create New Project를 클릭한다.





Java프로젝트를 선택하면 SDK(Software Development Kit)가 없다는 메세지가 뜬다. 아래 Download JDK를 눌러 JDK(Java development Kit)를 설치해주면 된다.





근데 자바 통합개발환경인 IntelliJ를 설치해줬는데 왜 또 설치를 하라고 할까?

IDE(Integrated Development Environment)는 프로그램 개발을 위한 편집기, 컴파일러, 디버거등 등 실행 모듈개발에 필요한 기능을 통합적으로 모아놓은것이고

SDK(Software Development Kit)는 소프트웨어 개발을 위해 모아놓은 도구 및 라이브러리이다. JDK는 SDK중 하나라고 보면 된다.




아래 사이트에서 다운로드 한다.


https://www.oracle.com/technetwork/java/javase/downloads



Next만 누르면 되기 때문에 캡쳐는 생략한다.





JDK 설치 후 다시 하면 자동으로 JDK가 선택된다.





프로젝트 이름을 정해주고 Finish를 누른다.





HelloWorld 프로젝트가 생성되었다.

오른쪽 상단의 ▶버튼을 눌러 실행하면 정상적으로 실행되어 Hello World!를 출력하는것을 볼 수 있다.

+ Recent posts