👨🏻‍💻iOS 공부/Swift_알고리즘 풀이

[LeetCode] Array (1)

728x90
반응형

LeetCode내 Easy모음집에서 먼저 풀이를 해볼 예정입니다~!

풀면 풀수록 먼저 문제를 정확하게 이해하는 것이 중요하다는 것을 깨닫습니다... 

우선 Array내에 풀고 싶은 문제들 먼저~!

 

1. Remove Duplicates from Sorted Array

 

배열 내의 중복된 원소들을 제거하는 것이 목표이다. 다만 새로운 배열을 만들지 않고(복사X) 기존 배열을 재배치하는 것이 주 포인트이다. 

[1,1,2,3,3,3] 
// [1,2,3]을 리턴해야함

그리고 기본적으로 배열들은 오름차순으로 정렬되어있는 상태이기에, 중복된 원소만 신경쓰면 된다. 

 

class Solution {
    func removeDuplicates(_ nums: inout [Int]) -> Int {
    	// 길이 0일때, 예외처리
        if (nums.count == 0) { return  0 }
        var i = 1
        
        // 첫 원소 제외하고 시작
        for n in 1..<nums.count {
			// 직전 원소와 비교 
            if nums[n-1] != nums[n] {  
            	// 다를 경우에만 새로 할당
                nums[i] = nums[n]    
                print(nums)
                // 중복되지 않은 수를 나타내는 i
                i += 1
            }
        }
        // i 만큼 인덱싱 됨
        return i
    }
}

[ 프로세스 ] 

 

1. 배열에 원소가 없는 경우, 0을 반환한다. 

2. 중복되지 않은 값을 할당하기 위한 index를 생성한다. 

3. 전체 배열을 돌면서 직전 원소와 같은지 아닌지를 판단한다.

      3-1. 직전 원소와 다를 경우, 우리가 찾는 값이다. 

      3-2. 기존 배열[index] 에 해당 값을 할당한다. 

      3-3. index를 1만큼 올려 다음 오게될 값을 기다린다! 

4. 배열의 길이만큼 반복한다. 

5. index만큼 배열을 잘라낸다!

 

[ 추가 정보 ] 

 

- inout : 

함수 내의 nums 파라미터는 let으로 할당되어 있다.

새로운 배열을 생성하지 않고 기존 배열을 수정해야하는데 let...

이 때 재할당이 가능하도록 만들어 주는 것이 inout 파라미터이다. 

 

 

아래의 예를 보고 이해해봅시다!

 

var test = 5

func(_ value: inout Int){
    // value는 let으로 지정되어 있어 값의 변경이 어려우나 inout 사용으로 가능해진 것 이다
    value += 1
    return value
}

func(value: &test) 
// 6 반환, &(앰퍼샌드) 기호를 써야한다.

 

 

2. Plus One

Int형의 원소들로 구성되어있는 배열들을 주고, 마지막 원소의 값에 1을 추가하는 일이다. 

언뜻 들으면 쉬워보이지만, 아래와 같은 케이스들을 모두 처리해주어야 한다. 

 

// Case 1
[8,8,9]
// [8,9,0]이 되어야 한다. 

// Case 2 
[9,9,9,9] 
// [1,0,0,0,0]이 되어야 한다.

 

눈치를 챘을 수도 있지만, 배열이 아니라 그냥 일반 숫자로 보고 +1을 하는 것 처럼 배열의 값이 바뀌고 있다. 

 

class Solution {
    func plusOne(_ digits: [Int]) -> [Int] {
        // 값 변경 가능하도록 var로 재할당
        var digits = digits
        // 맨 뒤의 원소부터 보기 위해 index 세팅
        var index = digits.count - 1
        
        // index 모두 돌기
        while index >= 0 {
            // 자리수가 안바뀌는 9 미만의 수일 경우
            if digits[index] < 9 {
                // 기존 수 + 1
                digits[index] += 1
                // 여기서 반환하여 함수 탈출!
                return digits
            }
            // 9인 경우이기에, +1 되기에 0으로 변경
            digits[index] = 0
            // 그 이전 원소 확인을 위해 index - 1
            // return을 따로 하지 않아 while문 돌도록
            index -= 1
        }
        // [9,9] [9,9,9]와 같은 경우 위 while문만 실핼할 경우
        // [0,0], [0,0,0]으로 되기에 가장 앞에 1을 추가해준다. 
        digits.insert(1, at: 0)
        return digits
    }
}

 

[ 프로세스 ]

 

1. let으로 지정되어있던 digits를 var로 재지정한다. 

2. 맨 마지막 원소를 보기 위해 index를 (길이-1)로 세팅한다.

3. 거꾸로 index를 돈다

       3-1. 마지막 자리가 자리 수가 바뀌지 않는 9 미만의 수 일 경우

               3-1-1. 마지막 자리수에 + 1을 한다. 

               3-1-2. 바로 return하여 값을 반환한다. (더 할게 없기 때문!)

       3-2. 마지막 자리가 9인 경우 해당 값을 0으로 변경한다. (나중에 이전 원소에 1씩 올려주려함)

       3-3. index를 하나씩 줄여 점점 앞으로 이동한다. 

4. [3-1-2]에서 반환되지 못한 경우, 즉 원소가 0으로만 전부 변경된 경우 맨 앞에 1을 추가해준다.

5. 해당 값을 반환한다. 

 

 

3. Move Zeros

이름처럼 배열 내 0인 값을 모두 뒤로 보내버리면 된다! 

아래의 예를 참고해서 이해해보자. 오름/내림차순은 신경쓰지 않고 0이 아닌 기존 값들의 순서만 유지하면 된다.

 

[1,0,4,0,12]
// [1,4,12,0,0] 으로 정렬되어야 함

// [1,0,4,0,12]
// [1,4,4,0,12]
// [1,4,12,0,12]
// [1,4,12,0,0] 
// 하나씩 앞으로 가져오고 (배열의 전체 길이 - 0이 아닌 원소의 수) 만큼 뒤에 0을 추가해준다.

 

아래 코드로 보자. 

 

class Solution {
    func plusOne(_ nums: inout [Int]) {
        var index = 0
        
        // 0이 아닌 값들
        for n in nums where n != 0 {
            nums[index] = n
            index += 1
        }
        
        for _ in 0..<nums.count-index {
            nums[index] = 0
            index += 1
        }
    }
}

 

[ 프로세스 ]

 

1. 먼저 index를 설정해준다. 

2. 0이 아닌 원소들을 순차적으로 돈다. 

       2-1. 맨앞부터 차곡차곡 0이 아닌 원소들을 할당해준다. 

       2-2. index는 1씩 증가시킨다. 

3. 0이 아닌 원소들이 앞에 다 위치했을 때, 원래 있던 0의 개수만큼 다시 채워줘야 한다. 

    그렇기에 (배열의 전체 길이 - 0이 아닌 원소의 수) 만큼 돌아준다.

       3-1. 돌면서 0을 추가해준다. 

       3-2. 마찬가지로 index를 1씩 올려 뒤로 이동한다. 

4. inout 파라미터를 사용했기에 따로 return하지 않아도 된다. (기존 배열을 변경한 것이기 때문!)

 

 

 

728x90
반응형