k번째 원소를 확인/변경하기 위해 O(k) 필요. 배열은 O(1)

임의의 위치에 원소를 추가/임의의 위치의 원소 제거는 O(1). 배열은 O(N)

메모리상에 연속되어 있지 않기때문에 cache hit rate가 낮지만 할당이 다소 쉬움

오버헤드는 O(N)

 

단일 연결 리스트, 이중 연결 리스트, 원형 연결 리스트 사용

STL에 리스트가 있고 이중 연결 리스트로 구현되어있음

 

면접에서 배열과 연결리스트를 비교하는걸 구술 시험으로 내기도 함

 

코딩 테스트에서 STL을 사용하지 못할 때 쓸 수 있는 야매 연결 리스트

더보기
#include <bits/stdc++.h>
using namespace std;

const int MX = 1000005;
int dat[MX], pre[MX], nxt[MX];
int unused = 1;

void insert(int addr, int num) {
	dat[unused] = num;
	
	pre[unused] = addr;
	nxt[unused] = nxt[addr];

	if (nxt[addr] != -1) pre[nxt[addr]] = unused;
	nxt[addr] = unused;
	
	unused++;
}

void erase(int addr) {
	nxt[pre[addr]] = nxt[addr];
	if (nxt[addr] != -1) pre[nxt[addr]] = pre[addr];
}

void traverse() {
	int cur = nxt[0];
	while (cur != -1) {
		cout << dat[cur] << ' ';
		cur = nxt[cur];
	}
	cout << "\n\n";
}

void insert_test() {
	cout << "****** insert_test *****\n";
	insert(0, 10); // 10(address=1)
	traverse();
	insert(0, 30); // 30(address=2) 10
	traverse();
	insert(2, 40); // 30 40(address=3) 10
	traverse();
	insert(1, 20); // 30 40 10 20(address=4)
	traverse();
	insert(4, 70); // 30 40 10 20 70(address=5)
	traverse();
}

void erase_test() {
	cout << "****** erase_test *****\n";
	erase(1); // 30 40 20 70
	traverse();
	erase(2); // 40 20 70
	traverse();
	erase(4); // 40 70
	traverse();
	erase(5); // 40
	traverse();
}

int main()
{
	ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);

	fill(pre, pre + MX, -1);
	fill(nxt, nxt + MX, -1);
	insert_test();
	erase_test();


	return 0;
}

 

연습문제

 

1406: 에디터

더보기
#include <iostream>
#include <string>
#include <list>

using namespace std;

int main(void)
{
	ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);

	list<char>	editor;
	string		str;
	int			m;

	cin >> str;

	for (auto s : str)
	{
		editor.push_back(s);
	}

	cin >> m;

	auto cursor = editor.end();

	while (m--)
	{
		char command;

		cin >> command;

		switch (command)
		{
		case 'L':
			if (cursor != editor.begin())
			{
				cursor--;
			}
			break;
		case 'D':
			if (cursor != editor.end())
			{
				cursor++;
			}
			break;
		case 'B':
			if (cursor != editor.begin())
			{
				cursor = editor.erase(--cursor);
			}
			break;
		default:
			char s;
			cin >> s;
			editor.insert(cursor, s);
			break;
		}
	}

	for (auto s : editor)
	{
		cout << s;
	}

	return 0;
}

 

리스트(그외 반복자가 있는 컨테이너도 마찬가지일듯)의 erase 사용시 삭제된 원소 다음 반복자를 반환해주기 때문에 갱신을 시켜주어야 한다.

그렇지 않고 계속 사용하다간 Segmentation fault를 발생시킨다

 

5397: 키로거

더보기
#include <iostream>
#include <string>
#include <list>

using namespace std;

int main(void)
{
	ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);

	int	tc;

	cin >> tc;

	while (tc--)
	{
		list<char>	editor;
		auto		cursor = editor.begin();

		string		str;

		cin >> str;

		for (auto s : str)
		{
			switch (s)
			{
			case '<':
				if (cursor != editor.begin())
				{
					cursor--;
				}
				break;
			case '>':
				if (cursor != editor.end())
				{
					cursor++;
				}
				break;
			case '-':
				if (cursor != editor.begin())
				{
					cursor = editor.erase(--cursor);
				}
				break;
			default:
				editor.insert(cursor, s);
				break;
			}
		}

		for (auto s : editor)
		{
			cout << s;
		}
		cout << '\n';
	}

	return 0;
}

 

1158: 요세푸스 문제

더보기
#include <iostream>
#include <string>
#include <list>

using namespace std;

int main(void)
{
	ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);

	list<int> josephus;

	int	n, k;
	int	idx = 1;

	cin >> n >> k;

	for (int i = 1; i <= n; ++i)
	{
		josephus.push_back(i);
	}

	auto iter = josephus.begin();

	cout << "<";

	while (true)
	{
		if (iter == josephus.end())
		{
			iter = josephus.begin();
		}

		if (idx % k == 0)
		{
			cout << *iter;
			iter = josephus.erase(iter); // 삭제된 원소 다음 반복자 반환

			if (josephus.empty())
			{
				break;
			}

			cout << ", ";
			idx++; // 삭제로 인해 자동으로 한칸이 밀렸으므로 인덱스도 맞춰줌

			continue;
		}
		
		iter++;
		idx++;
	}

	cout << ">";

	return 0;
}

 

 

'알고리즘 > 바킹독의 실전 알고리즘' 카테고리의 다른 글

[0x07] 덱(Deque)  (0) 2022.07.25
[0x06] 큐  (0) 2022.07.25
[0x05] 스택  (0) 2022.07.25
[0x03] 배열  (0) 2022.07.25
[0x02] 기초 코드 작성 요령  (0) 2022.07.25

임의의 위치에 있는 원소를 확인/변경 = O(1)

원소를 끝에 추가 = O(1)

마지막 원소를 제거 = O(1)

임의의 위치에 원소를 추가/임의 위치의 원소 제거 = O(N)

 

C++의 알고리즘 헤더에 fill이라는 함수가 있다.

fill(a, a+21, 0) // 해당 범위의 값을 0으로 초기화.

 

벡터의 = 연산은 깊은 복사이다.

 

연습문제의 핵심 키포인트는 값 자체를 배열의 인덱스로 써서 카운팅 하는것이다

'알고리즘 > 바킹독의 실전 알고리즘' 카테고리의 다른 글

[0x07] 덱(Deque)  (0) 2022.07.25
[0x06] 큐  (0) 2022.07.25
[0x05] 스택  (0) 2022.07.25
[0x04] 연결 리스트  (0) 2022.07.25
[0x02] 기초 코드 작성 요령  (0) 2022.07.25

c/c++ 코딩 시, cin/cout을 사용할거라면 ios::sync_with_stdio(0), cin.tie(0) 을 꼭 써주자.

ios::sync_with_stdio(0)은 c와 c++의 stream 동기화를 끊어준다. 이걸 사용하면 print, scanf 못쓴다.

cin.tie(0)은 어차피 채점 사이트에서는 출력값만 확인하기 때문에 버퍼를 비우지 않아도 상관없어서 쓴다.

endl 절대 쓰지 말고 개행문자로 쓸것.

 

코딩 테스트와 개발은 다르다.

코딩 테스트는 빠르게 정답만 내기만 하면 된다.

'알고리즘 > 바킹독의 실전 알고리즘' 카테고리의 다른 글

[0x07] 덱(Deque)  (0) 2022.07.25
[0x06] 큐  (0) 2022.07.25
[0x05] 스택  (0) 2022.07.25
[0x04] 연결 리스트  (0) 2022.07.25
[0x03] 배열  (0) 2022.07.25
field = [
['O', 'X', 'O', 'X', 'O'],
['X', 'O', 'X', 'O', 'X'],
['O', 'O', 'O', 'X', 'X'],
['X', 'X', 'X', 'O', 'O'],
['X', 'X', 'O', 'X', 'X'],
]

 

위와 같은 2차원 리스트가 존재할 때 인덱스 0, 0부터 2, 2까지 슬라이싱은 arr[0:2][0:2]가 아니다.

행으로 나누어서 1차원 리스트를 슬라이싱 한 것을 합쳐야 한다.

 

# 리스트 컴프리헨션 사용
field2x2 = [row[0:2] for row in field[0:2]]

# for문을 이용한 접근
for row in field[0:2]:
  row[0:2] # do something

 

 

'프로그래밍 > Python' 카테고리의 다른 글

코딩 테스트 준비를 위한 라이브러리  (0) 2022.07.22
내장함수  (0) 2022.07.22
[자료형] 집합  (0) 2022.07.22
[자료형] 딕셔너리(사전)  (0) 2022.07.22
[자료형] 리스트 & 튜플  (0) 2022.07.22

힙은 완전 이진트리로 구현된다. 우선순위 큐를 구현할때 힙을 사용한다.

이진 탐색 트리와 다르게 중복 값을 허용한다.

최소, 최대값만 루트 노드에 있고 그 외엔 큰 값이 상위레벨, 작은 값이 하위레벨에 있다는 정도의 반 정렬 상태를 유지한다.

pop 호출시 항상 루트노드가 제거되고 최소, 최대값이 나오게 된다.

삽입과 삭제에 시행되는 재정렬 과정이 O(NlogN) 이기 때문에 O(NlogN)을 보장한다.

보통 배열을 사용한다.

 

힙의 삽입 (최소힙 기준)

 

1. 힙에 새로운 요소가 들어오면 마지막 노드에 어어서 삽입한다

2. 부모 노드보다 값이 작으면 서로 바꾼다.

3. 2번이 수행되지 않을때까지 루트노드로 올라가며 반복한다.

 

힙의 삭제 (최소힙 기준)

 

1. 루트 노드를 삭제 한다. (가장 끝의 리프노드와 값 교환후, pop)

2. 둘 중 작은값을 가진 자식과 위치 교환

3. 조건을 만족하지 않거나 리프노드가 될 때까지 2번을 반복한다.

 

'프로그래밍 > 공부' 카테고리의 다른 글

C의 fread에 관한 의문점  (0) 2023.02.01
선언과 정의의 차이  (0) 2022.09.28
[자료구조] 트리, 그래프  (0) 2022.07.23
Effective C++ [4] 설계 및 선언  (0) 2015.07.10
Effective C++ [3] 자원관리  (0) 2015.07.09

+ Recent posts