자료구조는 데이터를 효율적으로 저장,접근,수정하기 위한 그릇이다. 코딩 테스트에서는 각 문제에 주어진 입력 데이터의 형태와 사용해야 하는 알고리즈에 따라 적절한 자료구조를 선정해 사용하는 것이 매우 중요하다.
기본 자료구조인 배열과 리스트는 비슷한 점도 많지만 다른 점도 많다. 파이썬에서는 리스트가 배열의 특성도 함께 내포하고 있어 크게 구분하여 사용하지는 않지만 두 자료구조의 특징과 동작 원리는 이해하고 있는 것이 좋다.
배열
리스트
리스트는 값과 포인터를 묶은 노드라는 것을 포인터로 연결한 자료구조이다.
특징
숫자의 합 구하기
포인트 → 리스트의 인덱스를 이용하기
n = int(input())
arr = input()
#이런식으로 입력받아도 상관없다. 어짜피 인덱스가 구분지어줄테니까.
answer = 0
for i in range(n):
answer+= int(arr[i])
print(answer)
평균 구하기
최고점수와 총합을 미리 계산해둔 상태에서 주어진 식에 대입하여 구하면 된다
한 과목과 관련된 수식을 총합한 후 관련 수식으로 변환해 로직을 간단하게 할 수 있다.
n = int(input())
arr = list(map(int,input().split()))
m = max(arr)
tmp = 0
for i in range(n):
tmp += arr[i]/m*100
print(tmp/n)
#혼자 풀어보았을 때
n = int(input())
arr = list(map(int,input().split()))
m = max(arr)
s = sum(arr)
print(s*100/m/n)
#책 풀이
#좀더 간결하다
구간 합은 합 배열을 이용하여 시간 복잡도를 더 줄이기 위해 사용하는 특수한 목적의 알고리즘 이다.
구간 합의 핵심 이론
구간 합 알고리즘을 활용하려면 먼저 합 배열을 구해야한다. 리스트 A가 있을 때 합 배열 S는 다음과 같이 정의 할 수 있다.
S[i] = A[0] + A[1] + A[2] + … + A[i-1] + A[i]
합 배열은 기존의 리스트 데이터를 전처리한 배열이라고 생각하면 된다.
합 배열을 미리 구해놓으면 기존 리스트의 일정 범위의 합을 구하는 시간 복잡도가 O(n)에서 O(1)로 감소한다.
A[i] ~ A[j] 까지의 리스트 합을 합배열 없이 구하는 경우 최악의 경우 i 가 0이고 j가 n인 경우로 시간 복잡도는 O(n)이다. 이런 경우 합배열을 이용하면 O(1)안에 답을 구할 수 있다.
합배열을 구하는 공식 : S[i] = S[i-1] + A[i]
구간 합을 구하는 공식 : S[j] - S[i-1]
A[2] ~ A[5] 까지의 구간합을 구하는 과정을 보자
n,m = map(int,input().split())
arr = list(map(int,input().split()))
s = sum(arr)
answer = []
for i in range(m):
start,end = map(int,input().split())
answer.append(sum(arr[:end]) - sum(arr[:start-1]))
for i in range(m):
print(answer[i])
# 처음에 작성한 코드
n,m = map(int,input().split())
arr = list(map(int,input().split()))
s_arr = [0] #시작 인덱스가 1이되도록 함
s = 0
answer = []
for i in range(n):
s += arr[i]
s_arr.append(s)
#합배열 구하기
for i in range(m):
start,end = map(int,input().split())
print(s_arr[end]-s_arr[start-1])
#합배열 공식 사용
from sys import stdin
n,m = map(int,stdin.readline().split())
numbers = list(map(int,stdin.readline().split()))
hap_numbers = [0]
tmp = 0
for i in numbers:
tmp += i
hap_numbers.append(tmp)
for i in range(m):
s,e = map(int,stdin.readline().split())
print(hap_numbers[e]-hap_numbers[s-1])
#수정된 코드
11659번: 구간 합 구하기 4h[i][j] = h[i][j-1] + h[i-1][j] - h[i-1][j-1] + n[i][j]
h[x2][y2] - h[x1-1][y2] - h[x2][y1-1] + h[x1-1][y1-1]
from sys import stdin
n,m = map(int,stdin.readline().split())
numbers = [[0] * (n+1)]
hap_numbers = [[0] * (n+1) for _ in range(n+1)]
for i in range(n):
arr = [0] + list(map(int,stdin.readline().split()))
numbers.append(arr)
print(numbers)
for i in range(1,n+1):
for j in range(1,n+1):
hap_numbers[i][j] = hap_numbers[i][j-1] + hap_numbers[i-1][j] - hap_numbers[i-1][j-1] + numbers[i][j]
for _ in range(m):
x1,y1,x2,y2 = map(int,stdin.readline().split())
answer = hap_numbers[x2][y2] - hap_numbers[x1-1][y2] - hap_numbers[x2][y1-1] + hap_numbers[x1-1][y1-1]
print(answer)