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



  문제해석

부호를 갖는 32비트의 주어진 정수를 가지고 그것이 4의 거듭제곱인지 판별하는 함수를 작성하라.




4의 거듭제곱을 2진수로 나타내보자. 100, 10000, 1000000,······ 첫 비트 1 오른쪽에 짝수개의 0을 가지고 있을 것이다. 4로 나누었을 때 깔끔하게 나누어 떨어지게 되므로 input/4의 값이나 input>>2의 값이 정확히 같을 것이다. 쉬프트연산자에 대해 잘 모른다면 아래 포스팅을 참고하자.


2019/03/18 - [프로그래밍문제풀기] - 쉬프트연산자




input값이 0보다 작은 경우엔 연산을 할 필요도 없다. 0보다 작거나 1일 경우에 예외처리 해 주고 아래의 코드에서는 0보다 작은 경우는 이미 처리했으니 >>산술쉬프트연산자를 쓰든 >>>논리쉬프트연산자를 쓰든 상관이 없다. 만약 함수의 앞부분에서 음수에 대한 예외처리를 해주지 않아도 결과 값에는 문제가 없겠지만 그럴 경우에 >>산술쉬프트연산자를 쓰면 굳이 할 필요 없는 -16/4 = -16>>2따위의 연산을 하게되므로 그 때는 >>>논리쉬프트연산자를 쓰는게 나겠다. (어쨌든 쉬프트연산자는 속도가 매우 빠르기 때문에 성능에는 전혀 상관이 없다!)


1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Solution {
    public boolean isPowerOfFour(int num) {
        if(num<=0return false;
        if(num==1return true;
        
        while(num!=1){
            if((num>>2)*4 != num){
                return false;
            }
            num=num>>2;
        }
        return true;
    }
}
cs



Worst Case(01000000 00000000 00000000 00000000)에도 쉬프트연산은 최대 15번으로 정해져 있으므로 시간복잡도는 O(1)이다. 또한 추가적인 메모리를 사용하지 않으므로 공간복잡도도 O(1)이다.




문제 출처 - https://leetcode.com/problems/power-of-four



쉬프트 연산자는 이름에서 볼 수 있듯이 bit를 오른쪽 또는 왼쪽으로 shift하는 연산자이다. 한가지 주의할 점은 비트를 이동할 때에는 한쪽으로 밀려난 비트가 반대편에서 다시 들어오는 것이 아니라 연산자의 종류에 따라 새로운 비트로 채운다. 쉬프트 연산자에는 3가지가 있다.




<<n Left shift 비트를 왼쪽으로 n만큼 이동하고 빈 공간을 0으로 채운다.

예시 : int a=17; a=a<<2; → a=68

00000000 00000000 00010001

00000000 00000000 01000100




>>n Arithmetic right shift 비트를 오른쪽으로 n만큼 이동하고 빈공간을 부호에 맞게 채운다.

예시 : int b=-325; b=b>>4; → b=-21

11111111 11111111 11111110 10111011

11111111 11111111 11111111 11101011

음수일때는 빈 공간을 1로 채운다.


예시 : int c=1048576; c=c>>5; → c=32768

00000000 00010000 00000000 00000000

00000000 00000000 10000000 00000000

양수일때는 빈 공간을 0으로 채운다.




>>>n Logical right shift 비트를 오른쪽으로 n만큼 이동하고 빈공간을 부호에 상관없이 0으로 채운다.

예시 : int d=-15000; d=d>>>6; → d=67108629

11111111 11111111 11000101 01101000

00000011 11111111 11111111 00010101





쉬프트 연산자는 산술연산자에 비해 속도가 엄청 빠르다. 하지만 프로그래밍을 할 때에는 나 혼자 개발하는 프로그램이 아니라면 속도 뿐만 아니라 코드의 가독성도 중요하다. 특수한 목적의 프로그래밍을 제외하고는 산술연산자를 굳이 속도 때문에 쉬프트연산자로 바꿀 필요는 없다. 쉬프트연산자는 10진 연산보다는 2진 연산에 주로 사용한다.





LeetCode 문제 중 난이도 EasyRemove Duplicates from Sorted Array이다. 문제 링크는 포스팅의 맨 마지막에 추가하였다. 언어는 Java를 사용했다.





  문제해석

정렬된 배열인 nums를 입력으로 받아 모든 요소들이 한번씩만 나타나도록 배열을 수정하고 길이를 리턴하여라. 새로운 저장공간을 사용하지 말고 input 배열을 수정하는 것으로 O(1)의 추가 메모리 내에서 해결해라.






이번 문제는 꽤 쉽다! 배열을 탐색하면서 중복값인지 아닌지 체크하고 중복값이 아닌 경우에만 앞에서부터 하나씩 저장해준다. 지금 탐색하고 있는 배열의 인덱스와 저장해야될 곳의 인덱스가 다르므로 저장해야 할 위치는 result라는 변수를 선언해서 기록한다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Solution {
    public int removeDuplicates(int[] nums) {
        
        //배열의 길이가 0일때의 예외처리
        if(nums.length==0return 0;
        
        int result=1;
        for(int i=1 ; i<nums.length ; i++){
            //요소가 중복값이 아닐 때에만 가져오고 리턴할 배열의 길이를 늘려줌
            if(nums[i]!=nums[i-1]){
                nums[result]=nums[i];
                result++;
            }
        }
        return result;
    }
}
cs


배열을 처음부터 끝까지 탐색해야 하므로 시간복잡도는 O(n)이고 저장할 때 필요한 변수 하나만 선언하면 되므로 공간복잡도는 O(1)이다.


문제 출처 - https://leetcode.com/problems/remove-duplicates-from-sorted-array

+ Recent posts