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하지 않아도 된다. (기존 배열을 변경한 것이기 때문!)