본문 바로가기
Study/코딩테스트(JS)

05.배열

by dailycoding777 2025. 2. 18.

배열이란

같은 종류의 데이터를 순서대로 저장하는 자료구조

  • 하나의 변수 이름으로 동일한 타입의 데이터를 그룹화해서 관리
  • 인덱스(index)라는 것으로 원하는 데이터에 임의 접근할 수 있음
  • 인덱스 번호는 0부터 시작함

배열 생성자를 이용하는 법

const arr1 = new Array(6); [undefined,undefined, ...]
const arr2 = [...new Array(6)].map((_,i)=> i + 1) //[1,2,3,4,5,6]

array.fill(value,start,end)

특정 범위를지정한 값으로 채우는 메서드

const arr = [1,2,3,4,5]
arr.fill(0,1,4) // index 1부터 4이전까지 채움(1~3) 0으로 채움
console.log(arr) //[1,0,0,0,5]

0이 값이고 인덱스넘버 1번 ~4이전까지 0으로 채우겠다.

배열 전체를 채우고 싶다면:

const arr = new Array(5).fill(1);
console.log(arr); // [1, 1, 1, 1, 1]

배열과 차원

차원(Dimension)이 뭐냐?

배열이 한줄로 된 1차원 배열도 있지만 2차원,3차원,N차원 배열도 있음.

즉 , 배열안에 또 다른 배열이 있는 구조

2차원 배열 예시 (배열 안에 배열)

const matrix = [
	[1,2,3], // 첫번째 행
	[4,5,6], // 두번째 행
	[7,8,9] // 세번째 행
]

console.log(matrix[0][0]); // 1 ( 첫번째 행 , 첫번째 원소 )
console.log(matrix[1][2]); // 6 ( 두번째 행 , 세번째 원소 )

3차원 배열 예시 (배열 안에 배열 안에 배열)

const cube = [
  [  // 첫 번째 층
    [1, 2],
    [3, 4]
  ],
  [  // 두 번째 층
    [5, 6],
    [7, 8]
  ]
];

console.log(cube[0][1][1]); // 4 (첫 번째 층 → 두 번째 행 → 두 번째 원소)
console.log(cube[1][0][0]); // 5 (두 번째 층 → 첫 번째 행 → 첫 번째 원소)

이런 식으로 배열을 쌓아올려서 N차원 배열도 만들 수 있습니당! 🚀


정리

차원 구조 예시

1차원 리스트 [1, 2, 3, 4]
2차원 표 (행, 열) [[1,2], [3,4]]
3차원 큐브 (층, 행, 열) [[[1,2], [3,4]], [[5,6], [7,8]]]

05-2 배열의 효율성

배열 연산의 시간복잡도

배열은 임의 접근이라는 방법으로 배열의 모든 위치에 있는 데이터를 단 한번에 접근할 수 있다.

따라서 데이터에 접근하기 위한 시간복잡도는 O(1)이다.

빅오표기법

🔹 배열(Array) 연산 시간 복잡도 정리

연산 종류 배열 크기 시간 복잡도 설명

접근 (Access) O(1) arr[i]와 같이 인덱스를 사용하면 한 번에 접근 가능  
탐색 (Search) 정렬 X O(n) 특정 값을 찾기 위해 전체 배열을 탐색해야 함
탐색 (Search) 정렬 O O(log n) 이진 탐색(Binary Search)을 사용하면 O(log n)
삽입 (Insert) 맨 끝 O(1) push() 연산은 배열 끝에 추가할 때 빠름
삽입 (Insert) 맨 앞 O(n) 모든 요소를 한 칸씩 뒤로 밀어야 함
삽입 (Insert) 중간 O(n) 중간에 넣을 때도 뒤 요소들을 밀어야 함
삭제 (Delete) 맨 끝 O(1) pop() 연산은 배열 끝에서 제거할 때 빠름
삭제 (Delete) 맨 앞 O(n) 모든 요소를 한 칸씩 앞으로 당겨야 함
삭제 (Delete) 중간 O(n) 중간 요소 삭제 시 뒤 요소를 한 칸씩 당겨야 함

배열의 특징

  • 배열은 인덱스를 통해 직접 접근이 가능해서 O(1)로 빠름.
  • 하지만 중간 삽입/삭제 시 요소를 이동해야 해서 O(n)의 비용이 발생함.

효율적인 배열 연산

  • 삽입/삭제가 많으면 Linked List(연결 리스트)가 더 적합할 수 있음.
  • 탐색이 많다면 정렬 후 Binary Search(이진 탐색) 활용하면 성능 개선 가능.

예시 ) 배열 요소 추가 메소드

1️⃣ push() → 배열 뒤에 추가 (O(1))

const arr = [1, 2, 3];
arr.push(4, 5);
console.log(arr); // [1, 2, 3, 4, 5]

2️⃣ concat() → 배열 합치기 (O(N))

const arr1 = [1, 2];
const arr2 = [3, 4];
const newArr = arr1.concat(arr2);
console.log(newArr); // [1, 2, 3, 4]

3️⃣ 스프레드 연산자 (...) → 배열 복사 & 추가 (O(N))

const arr = [1, 2];
const newArr = [...arr, 3, 4]; // 뒤에 추가
console.log(newArr); // [1, 2, 3, 4]

const anotherArr = [0, ...arr]; // 앞에 추가
console.log(anotherArr); // [0, 1, 2]

4️⃣ unshift() → 배열 앞에 추가 (O(N))

맨 뒤에 요소 추가 → Push

맨 뒤에 요소 삭제 → pop

const arr = [2, 3];
arr.unshift(0, 1);
console.log(arr); // [0, 1, 2, 3

5️⃣ splice() → 배열 중간에 추가 (O(N))

const arr = [1, 2, 4, 5];
arr.splice(2, 0, 3); // 2번 인덱스에 '3' 추가
console.log(arr); // [1, 2, 3, 4, 5]

배열 요소 삭제 메소드

1️⃣ pop() → 배열 뒤에서 삭제 (O(1))

const arr = [1, 2, 3, 4];
arr.pop();
console.log(arr); // [1, 2, 3]

2️⃣ shift() → 배열 앞에서 삭제 (O(N))

const arr = [1, 2, 3, 4];
arr.shift();
console.log(arr); // [2, 3, 4]

3️⃣ splice() → 배열 중간 요소 삭제 (O(N))

const arr = [1, 2, 3, 4, 5];
arr.splice(2, 2); // 2번 인덱스(세 번째 요소) 삭제
console.log(arr); // [1, 2, 5]

🏆 정리

메소드 역할 시간 복잡도

push() 뒤에 추가 O(1)
concat() 배열 합치기 O(N)
... (스프레드) 새로운 배열 생성 후 추가 O(N)
unshift() 앞에 추가 O(N)
splice(index, 0, item) 중간에 추가 O(N)
pop() 뒤에서 삭제 O(1)
shift() 앞에서 삭제 O(N)
splice(index, count) 중간 삭제 O(N)

👉 빠르게 추가/삭제하려면 push() & pop()이 최고!

👉 splice()는 중간에 추가/삭제할 때 사용하지만 느릴 수 있음!


고차 함수를 이용하여 데이터에 특정한 연산 적용

고차 함수(Higher-Order Function, HOF)는 함수를 인자로 받거나, 함수를 반환하는 함수

✔ 콜백 함수를 활용해 코드의 유연성을 높일 수 있음

✔ map, filter, reduce같은 메서드가 대표적인 고차 함수

✔ 클로저(Closure) 패턴과 결합하면 강력한 기능 구현 가능

1.함수를 인자로 받는 고차 함수

function repeat(n, action){
	for(let i = 0; i < n; i++){
		action(i);		
	}
}

repeat(5,console.log);
  • repeat(5,console.log) → repeat 함수가 console.log 를 인자로 받아서 0부터 4까지 출력
  • repeat 함수 자체가 “함수를 인자로 받는 고차함수”

2. 함수를 반환하는 고차 함수

function makeMultiplier(factor){
	return function(num){
		return num * factor;
	};
}

const double = makeMultiplier(2);
const triple = makeMultiplier(3);
  • makeMultiplier(2) → num * 2 를 수행하는 함수 반환
  • makeMultiplier(3) → num * 3 를 수행하는 함수 반환

이런 패턴을 커링(Currying) 이라고 한다.

3. map, filter, reduce 활용 (대적인 고차 함수)

✔ map(): 배열의 각 요소를 변형

const numbers = [1, 2, 3, 4, 5];
const squared = numbers.map(n => n * n);
console.log(squared); // [1, 4, 9, 16, 25]

✅ map() 함수는 배열의 각 요소를 변형하는 고차 함수

✅ n => n * n 함수를 인자로 받아 실행


✔ filter(): 조건에 맞는 요소만 걸러냄

const numbers = [1, 2, 3, 4, 5];
const evens = numbers.filter(n => n % 2 === 0);
console.log(evens); // [2, 4]

✅ filter() 함수는 조건을 만족하는 요소만 걸러주는 고차 함수

✅ n % 2 === 0인 값들만 필터링


✔ reduce(): 배열을 하나의 값으로 줄이기

const numbers = [1, 2, 3, 4, 5];
const sum = numbers.reduce((acc, cur) => acc + cur);
console.log(sum); // 15

✅ reduce() 함수는 배열의 값을 누적해서 하나로 줄이는 고차 함수

✅ (acc, cur) => acc + cur 로 누적해서 더함


📌 4. setTimeout()도 고차 함수!

function delayedGreeting(name) {
  setTimeout(() => {
    console.log(`안녕, ${name}!`);
  }, 2000);
}

delayedGreeting("민호"); // 2초 후 "안녕, 민호!" 출력

✅ setTimeout()은 콜백 함수(익명 함수)를 인자로 받음

✅ 따라서 setTimeout()도 고차 함수

'Study > 코딩테스트(JS)' 카테고리의 다른 글

08.해시  (0) 2025.02.25
07. 큐  (0) 2025.02.25
06. 스택  (0) 2025.02.25
04.코딩테스트 필수 문법  (1) 2025.02.11
03.알고리즘의 효율 분석(BigO,시간&공간 복잡도)  (0) 2025.01.21