본문 바로가기
코딩 테스트

[03-3] 배열을 알아보자(활용편)

by 너티드코오딩 2023. 11. 9.

여태까지 배열의 구조와 원리를 알아보았다.

 

역시 가장 중요한건, 그래서 코테에서 어떻게 쓰이는데?

결론부터 말하면, 배열은 반복문에서 많이 쓰인다.

 

list는 순서가 있기 때문에, 순차적으로 접근하는 반복문과 잘어울린다.

 

1. for 문

우리가 쉽게 생각하는 구조인 for문은 대표적 리스트 활용사례라고 봐도 무방하다.

예를 들어서

A = [5, 8, 3, 2, 11, 9, 4, 1, 13] 라는 리스트가 주어졌을 때,

"두개의 값 합했을 때 10이 나오면 True, 넘지 않으면 Fasle를 반환하시오"

라는 문제가 주어졌다면 A[i] + A[j]를 활용해야 겠다는 생각을 하게 된다.

 

자연스럽게 for문을 떠올리고, for문 안에 for 문인 이중for문을 구성하는데

우선은 이렇게 자연스럽게 for for를 써야겠다 라는 생각을 할 수 있는 사고력을 키우는데 집중하자

여기서 심화시킨다면 for문을 n번 하는구나, 그리고 그 안에서 for문을 n번 반복하니까 O(n²)이겠구나

라고 생각해보는 능력을 기르자.

 

정리하자면

1. for문을 돌리는 이유: list에서 값을 하나씩 테스트하려는 것

2. for문을 써야겠다!: list를 활용해야 하니까 O(n).. 이중이면 O(n²)이니까 n≤10⁴ 까지 가능하겠구나

 

2. 정렬

내림차순, 오름차순 정렬을 한다면 결국 리스트를 활용한다.

여기서 중요한건, 정렬에서 시간 복잡도는 O(nlogn)이다.

 

정렬이 왜 중요하냐면, 정렬은 낮은 시간 복잡도를 가지고 있지만, 파급력이 어마어마 하기 때문이다.

앞선 예시와 동일한 케이스를 가져와보자.

A = [5, 8, 3, 2, 11, 9, 4, 1, 13]   이 리스트에서 더해서 10이 나오면? 해서 for i, j 를 썼다.

하지만 오름차순 정렬을 해보자

A = [1, 2, 3, 4, 5, 8, 9, 11, 13] 로 정렬할 수 있고, 양 끝에 포인터를 두어서 1, 13을 찍어 더한다.

10이 넘네? 그러면 13을 왼쪽으로 옮겨서 1, 11로 한다. 어 넘네? 1, 9 성공!

만약에 10보다 작다면, 왼쪽 포인터를 오른쪽으로 옮기면 되겠지.

 

이처럼 정렬은 복잡한 가정을 줄여주기 때문에 굉장히 효율적이다. 낮은 시간복잡도를 가지고, 굉장히 파워풀하다.

 

항상 코드를 구현할 때는

1. 어떤 문제인가?

2. 어떻게 이 문제를 풀 수 있을까?

3. 코드를 그림으로 표현해보자(그려보자)

4. 그린 코드를 구현하자

 

4단계의 스텝으로 진행하면 좋다.

 

이 문제에 적용해보면

1. 더해서 10을 만들어야하는구나.. 정렬이 안되어 있네.. 리스트를 다 더하는건가? 조건을 보자. n≤10⁴이네

2. 리스트 원소를 하나씩 다 더해서 구할 수 있겠군! O(n²)이라서 너무 시간복잡도가 타이트하네..정렬을 해볼까? O(nlogn)이니까 할만할 것 같아. 정렬해서 끝을 하나씩 더해볼까? 오케이!

3. A.sort() ⇒ O(nlogn)이고, 왼쪽 포인트를 left, 오른쪽을 right 변수로 써봐야겠군. l=0, r=n-1 이군!

4. nums[l] + nums[r] == traget ⇒True 만약 타켓보다 작다면? l+1, 타켓보다 크다면? r-1. 언제까지? l<r되기 전까지!

 

자 생각해보면? 정렬은 O(nlogn), 해당 반복문은 결국 random access로 접근하니 O(1)이고.. 안에서 n번만큼 돌 수 있으니 O(n) 이구나. 그렇다면? O(nlogn)+O(n)이니까 O(nlogn)의 복잡도를 갖는구나!

 

정렬 한방에 모든게 수월해졌다!

'코딩 테스트' 카테고리의 다른 글

[04-2] 연결 리스트의 활용  (2) 2023.11.09
[04-1] 연결 리스트란?  (2) 2023.11.09
[03-2] 배열을 알아보자(Dynamic Array)  (1) 2023.11.09
[03-1] 배열을 알아보자(Static Array)  (0) 2023.11.08
[02] 알고리즘이란?  (0) 2023.11.08