- 알고리즘 프로그래밍 훈련에 도움되는 웹사이트 몇 곳을 공유드립니다.
- 백준 온라인 저지 (Baekjoon Online Judge) : https://www.acmicpc.net/
-
백준 온라인 저지는 대한민국 최초의 알고리즘 문제 풀이 사이트입니다. 다양한 난이도와 주제의 문제들을 제공하며, C++, Java, Python 등 다양한 언어를 지원합니다.
- 프로그래머스(Programmers) : https://programmers.co.kr/
-
프로그래머스는 코딩테스트를 준비하는 개발자들을 위한 온라인 교육 사이트입니다. 프로그래머스에서는 다양한 주제의 문제들을 제공하며, 알고리즘 뿐만 아니라 SQL, 데이터 분석, 인공지능 등 다양한 분야의 문제를 풀어볼 수 있습니다.
- 리트코드(LeetCode) : https://leetcode.com/
-
리트코드는 알고리즘 문제를 제공하는 미국의 온라인 교육 플랫폼입니다. 대부분의 문제가 영어로 제공되지만, 다양한 주제와 난이도의 문제들을 제공하며, 다양한 언어를 지원합니다.
- 해커랭크(HackerRank) : https://www.hackerrank.com/
-
해커랭크는 알고리즘과 데이터 구조, 수학 등 다양한 분야의 문제를 제공하는 온라인 교육 사이트입니다. 문제의 난이도와 유형이 다양하며, 다양한 언어를 지원합니다.
- 코드포스(Codeforces) : https://codeforces.com/
- 코드포스는 알고리즘 대회를 주최하며, 대회 이외에도 다양한 주제와 난이도의 문제를 제공하는 온라인 교육 사이트입니다. 대회에서는 랭킹이 제공되며, 문제의 난이도와 유형이 다양합니다.
분수의 덧샘
- 문제링크
분수의 덧셈
분자 = 분자1분모2 + 분자2분모1; 분모 = 분모1*분모2;
기약분수
- 기약분수 = 분자와 분모를 최소공배수로 나누면 얻을수 있음
최대공약수 gcd(greatest common divisor)
- 두 숫자를 나누어 떨어지게 할수 있는 가장큰수 = 두 숫자를 나눈 나머지가 0이 될때의 값
- 항상 큰수에서 작은수를 나누어야 한다.
//javascript
function gcd(a,b){
var min = Math.min(a,b);
var max = Math.max(a,b);
var _gcd = min;
while(true){
if(max % min == 0)break;
_gcd = max % min;
max = min;
min = _gcd;
}
console.log("gcd:"+_gcd);
return _gcd;
}
최소공배수 lcm(least common multiple)
- 두 수에 서로 공통으로 존재하는 배수 중 가장 작은 수
- 두 수를 곱한 후 최대공약수로 나눈수
//javascript
function lcm(a,b){
var _gcd = gcd(a,b);
var _lcm = a*b/_gcd;
console.log("lcm:"+_gcd);
return _lcm;
}
중앙값 구하기
- 문제링크
- javascript sort를 이용하여 정렬 가능
- var answer = array[Math.round(array.length/2)-1];
-
정렬 후 전체길이의 반절 -1 (0 주소 부터 시작하기 때문)하여 문제해결
- 값의 크기가 비교되는게 아니라 앞글자부터 비교되어 에러가 난 경우
- sort()는 문자열의 유니코드 순서를 따르므로
- sort((a,b) => a-b)로 해주어야 한다.
최빈값 구하기
//javascript
function solution(array) {
var counters = [];
counters[0] = 0;
for(var i=0; i<array.length; i++){
if(Number.isInteger(counters[array[i]])){ //주소에 들은 값이 정수인지 확인
counters[array[i]]++;
}else{ //아니라면 초기값 입력
counters[array[i]] = 1;
}
}
var appear_time = 0;
var max_appear = -1;
for(var i=0; i<counters.length; i++){
if(counters[i] == appear_time){
max_appear = -1;//최빈값 중복시 최빈값 -1로 변경
}
if(counters[i] > appear_time){
appear_time = counters[i]; //최빈값 등장시 최빈량 저장
max_appear = i; //최빈값 저장
}
}
console.log(counters);
var answer = max_appear;
return answer;
}
짝수는 싫어요
function solution(n) {
var answer = [];
for(i=1; i<=n; i+=2){
answer.push(i);
}
console.log(answer);
return answer;
}
Javascript Reduce를 이용한 배열의 모든 숫자 더하기
var numbers = {1,2,3,4,5};
var sum = numbers.reduce((a,b) => (a+b));
배열 뒤집기
num_list.sort((a, b) => -1);
return num_list.reverse();
문자열 뒤집기
function solution(my_string) {
var strings = my_string.split('').reverse();
var answer = strings.reduce((a,b) => (a+b));
return answer;
}
var answer = [...my_string].reverse().join(""); //스프레드문법
문자 반복하기
function solution(my_string, n) {
var answer = [...my_string].map(v => v.repeat(n)).join("");
console.log(answer);
return answer;
}
문자열 치환하기
function solution(my_string, letter) {
const re = new RegExp(`${letter}`, 'g');
var answer = my_string.replace(re,"");
return answer;
}
my_string.replaceAll(letter, "");
function solution(numbers, num1, num2) {
var str = numbers.join(''); //하나의 문자열로 합시기
var new_str = str.substr(num1,num2-num1+1); //시작인덱스와 끝인덱스 문자만 자르기
var answer = new_str.split(''); //각문자를 배열로 변환
answer = answer.map(Number); //배열에 들어간 각각의 문자열을 숫자로 치환
answer = answer.map(x => Number(x)); //상동
return answer;
//2가지 케이스에 대한 테스트 실패가 나옴
}
function solution(numbers, num1, num2) {
var answer = numbers.slice(num1,num2+1);
return answer;
}
.slice, .splice
- splice(start, deleteCount)
- slice(begin, end)
- splice 메소드는 기존 배열에 영향을 주지만 slice 메소드는 기존 배열에 영향을 주지않습니다
var rank = [...emergency];
rank.sort((a,b) => b-a);
answer = emergency.map((x) => rank.indexOf(x)+1);
return answer;
어떠한 숫자를 이루는 약수의 개수 == 순서쌍
function solution(n) {
var answer = 1;
for(var i=0; i<n; i++){
if(n%i == 0)answer++;
}
return answer;
}
모스부호 치환
function solution(letter) {
morse = {
'.-':'a','-...':'b','-.-.':'c','-..':'d','.':'e','..-.':'f',
'--.':'g','....':'h','..':'i','.---':'j','-.-':'k','.-..':'l',
'--':'m','-.':'n','---':'o','.--.':'p','--.-':'q','.-.':'r',
'...':'s','-':'t','..-':'u','...-':'v','.--':'w','-..-':'x',
'-.--':'y','--..':'z'
}
var arr = letter.split(" ");
for(var i=0; i<arr.length; i++){
arr[i] = morse[arr[i]];
}
var answer = arr.join("");
return answer;
}
letter.split(' ').map(v=>morse[v]).join('');
return letter.split(' ').reduce((prev, curr) => prev + morse[curr], '')
가위바위보 - 글자 치환
- 삼항연산자 : https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Operators/Conditional_Operator
- 문제링크
function solution(rsp) {
var arr = rsp.split("");
arr = arr.map((x) => x==2 ? 0 : x==0 ? 5 : 2);
var answer = arr.join("");
return answer;
}
경우의 수 계산 - 팩토리얼
function solution(balls, share) {
//balls!/(balls-share)!*share!
console.log(fectorial(2));
var answer = Math.round(fectorial(balls)/(fectorial(balls-share)*fectorial(share)));
return answer;
}
function fectorial(num){
if (num < 0){
return -1;
}else if(num==0){
return 1;
} else {
return num*fectorial(num-1);
}
}
- Math.round는 왜? 부동소숫점 오류 - https://joooing.tistory.com/entry/Javascript-%EC%86%8C%EC%88%98%EC%A0%90floating-point-%EA%B3%84%EC%82%B0-%EC%98%A4%EB%A5%98
구조 분해
function solution(dot) {
const [num,num2] = dot;
const check = num * num2 > 0;
return num > 0 ? (check ? 1 : 4) : (check ? 3 : 2);
}
배열에 갑추가, 빼기
- .push() : 배열의 맨 끝에 값을 추가한다.
- .unshift() : 배열의 맨 앞에 값을 추가한다.
##배열에 값을 제거하는 함수
- .pop() : 배열의 맨 끝에 값을 제거한다.
- .shift() : 배열의 맨 앞에 값을 제거한다.
정규표현식
- [^0-9] : 숫자가 아니면
- [0-9] : 숫자면
- [\d] : desimal 이면
- [^\d] : desimal 아니면
- [a-zA-Z] : 영문이면
- [^a-zA-Z] : 영문이 아니면
소인수 분해 하기
function solution(n) {
var arr = [];
for(var i=2; i<=n; i++){
if(n%i==0){
arr.push(i); //소인수 입력
n=n/i; //소인수값으로 나눔
i--; //값이 나누어 떨어지면 재시도
}
}
arr = arr.filter((v, i) => arr.indexOf(v) === i) //중복제거
var answer = arr;
return answer;
}
function prime_factor(n){
var arr = [];
for(var i=2; i<=n; i++){
if(n%i==0){
arr.push(i); //소인수 입력
n=n/i; //소인수값으로 나눔
i--; //값이 나누어 떨어지면 재시도
}
}
arr = arr.filter((v, i) => arr.indexOf(v) === i)
//중복제거
return arr;
}
- 컨트럴 제트
- 문제링크
function solution(s) {
var ss = s.split(" ");
var keep = ss[0];
var answer = ss.reduce((a,b) => {
if(b!="Z"){
a = Number(a);
b = Number(b);
keep = b;
return (a+b);
}else{
a = Number(a);
return (a-keep);
}
});
return answer;
}
- 테스트케이스 678번 실패
function solution(s) {
var ss = s.split(" ").map(Number);
var answer = ss.reduce((acc,current,index,arr) => !isNaN(current)?acc+current:acc-arr[index-1]);
return answer;
}
- keep이라고 해서 숫자를 저장하는 방식이 문제였나 본데
reduce
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce
- 매개변수
arr.rebuce((accumulator,currentValue,currentIndex,array)=>{return 연산후값},initialValue);
arr.rebuce((acc,current,index,arr)=>{return 연산후값},init);
- callbackFn : 배열의 각 요소에 실행할 함수
- accumulator : 이전 호출의 결과값
- currentValue : 현재 요소의 값
- currentIndex : 배열에서 인덱스 위치
- array : 배열
- initialValue : 콜백이 처음 호출될 때 초기화되는 값
369
function solution(order) {
var arr = order.toString().split('');
console.log(arr);
var answer = arr.reduce((a,b) => a+(b==3)+(b==6)+(b==9), 0);
return answer;
}
- 숫자에 블린을 덧셈해서 카운트에 사용하기도 하네
아스키코드
- 참고 링크 : https://developer-talk.tistory.com/880
문자열.charCodeAt(0); //0번째 글자의 아스키코드 반환
String.fromCharCode(); //UTF-16코드를 문자로 반환
문자열.codePointAt(); //charCodeAt과 유사하나 표현할수 있는 정수의 범위가 더 크다
String.fromCodePoint(code1,code2 ... codeN); //지정된 코드 포인트 시퀀스를 문자열로 변환
필터
function solution(n, numlist) {
var answer = numlist.filter(x => x%n==0);
return answer;
}
자릿수 더하기
function solution(n) {
var arr = [...n.toString()];
var answer = arr.reduce((a,b)=>Number(a)+Number(b));
return answer;
}
- 에러 : reduce에 초기값이 없음으로 초기값이 string으로 시작됨
arr.reduce((a,b)=>Number(a)+Number(b),0);
으로 초기값을 잡고 시작하거나 arr을 map(Number)하여 숫자로 변환 후 사용
문자열 검사
function solution(str1, str2) {
var regex = new RegExp(`${str2}`, 'g');
var answer = regex.test(str1)?1:2;
return answer;
}
제곱근 정수 판별
function solution(n) {
var sqrt = Math.sqrt(n);
var answer = sqrt==Math.floor(sqrt)?1:2;
return answer;
}
문자열 치환
function solution(s) {
var answer = s.toLowerCase();
var regex = /^\w| \w/g; //문자로 시작하거나(|)스페이스가 앞에 붙은 문자
answer = answer.replaceAll(regex,function(v){
return v.toUpperCase();
});
return answer;
}
괄호
function solution(s){
var regex = /\(\)/gm;
while(regex.test(s)){
s = s.replaceAll(regex,"");
}
return s.length == 0;
}
- 리플레이스로 해결하려하니 효율성 테스트에서 실패
function solution(s){
var arr = [...s];
var counter = arr.reduce((a,b)=>b==")"?a-1:a+1,0);
return counter==0 && arr[0]=="(";
}
- 플러스마이너스 0이고 (로 시작한다면. 통과
- 갯수만 가지고는 안되나? ())(() 반례
function solution(s){
var arr = [...s];
var counter = arr.reduce((a,b)=>b=="("?a+1:a>0?a-1:a-100,0);
console.log(counter);
return counter == 0;
}
- 시간초과
- 테스트 17 〉 통과 (2.21ms, 33.5MB)
- 테스트 18 〉 통과 (3.40ms, 33.5MB)
function solution(s){
var arr = [...s];
var counter = 0;
for(var i=0; i<arr.length; i++){
counter = arr[i]=="("?counter+1:counter>0?counter-1:counter-100
}
console.log(counter);
return counter == 0;
}
- 같은내용을 reduce가 아닌 for로 돌려서 해결
- 테스트 17 〉 통과 (2.25ms, 33.6MB)
- 테스트 18 〉 통과 (3.30ms, 33.5MB)
- 테스트 케이스에서는 차이가 별로 안나는데.
문자의 사용 만족
function solution(spell, dic) {
var answer = 0;
var exist = true;
for(var i=0;i<dic.length; i++){
if(dic[i].length != spell.length) continue; //글자수가 안맞으면 넘어가
console.log(dic[i]);
exist = true;
for(var j=0; j<spell.length; j++){
dic[i] = dic[i].replace(spell[j],"");
if(dic[i].length != spell.length-1-j){ //두개이상 지워지면 넘어가
exist = false;
break;
}
}
if(exist)return 1;
}
return 2;
}
function solution(p, d) {
return d.some(s => p.sort().toString() == [...s].sort().toString()) ? 1 : 2;
}
fill
- arr3.fill(‘A’, 1, 3);
- 인덱스 1부터 3 까지 ‘A’로 채움
등수매기기
function solution(score) {
var i=0;
score = score.map(function(v){return (v[0]+v[1])/2;}); //평균내기
var arr = [...score];
arr.sort((a,b)=>b-a); //등수내기
console.log(arr);
var answer = score.map(v => arr.indexOf(v)+1); //현점수가 몇순위인지 확인하여 배열에 넣기
return answer;
}
십진수 이진수
function solution(bin1, bin2) {
var de1 = parseInt(bin1, 2); //2진수를 10진수로
var de2 = parseInt(bin2, 2);
console.log(de1);
console.log(de2);
var answer = (de1+de2).toString(2); //10진수를 2진수로
return answer;
}
배열의 비교
const equals = (a, b) => a.length === b.length && a.every((v, i) => v === b[i]);
function solution(before, after) {
var arr1 = [...before];
var arr2 = [...after];
arr1 = arr1.sort();
arr2 = arr2.sort();
console.log(arr1);
console.log(arr2);
var answer = equals(arr1, arr2);
return answer;
}
문자열내 포함여부
- String.indexOf(): 문자열에 어떤 문자열이 포함되어있는지 확인
- String.includes(): 문자열에 어떤 문자열이 포함되어 있는지 확인
- String.startsWith(), String.endsWith(): 문자열이 어떤 문자열로 시작하거나 끝나는지 확인