알고리즘 1일차

개발 log·2021년 8월 2일
0

알고리즘

목록 보기
10/11

문자열과 해싱




숫자 통일

  1. zero변수와 one 변수 생성
  2. s 문자열의 첫번째 인덱스에 따라 변수에 카운트
  3. 반복문을 s문자열의 두번째 인덱스부터 반복하며 왼쪽과 본인이 같은지 확인하고
  4. 1이면 one카운트 0이면 zero 카운트
  5. answer에 one과 zero중 큰 값을 할당
function solution(s) {
  let answer;
  let zero = 0,
    one = 0;
  if (s[0] === "1") one = 1;
  else zero = 1;
  for (let i = 1; i < s.length; i++) {
    if (s[i - 1] !== s[i]) {
      if (s[i] === "1") one++;
      else zero++;
    }
  }
  answer = Math.min(one, zero);
  return answer;
}

상태변화

  1. s1문자열에서 반복문을 돌며
  2. s1의 값과 s2의 값을 비교하여 같지 않고 s가 0이면 zero카운트 1이면 one 카운트
  3. zero값과 ,one값 중 큰값 반환
function solution(s1, s2) {
  let zero = 0,
    one = 0;
  s1.split("").forEach((s, i) =>
    s !== s2.split("")[i] ? (s === "0" ? zero++ : one++) : false
  );
  return Math.max(zero, one);
}

접미사 정렬

  1. 빈 배열을 생성하고
  2. s문자열의 반복문을 돌며 s문자열의 접미사들을 배열에 push
  3. 정렬 후 반환
function solution(s) {
  let arr = [];
  for (let i in s.split("")) arr.push(s.slice(i));
  return arr.sort();
}

공통문자가 없는 단어

  1. 반복문을 조금이라도 덜 돌기 위해 words를 정렬
  2. 이중 반복문과 isUnique함수를 이용하여 공통문자 탐색
  3. tmp와 answer를 비교해가며 최대값을 answer에 할당
  4. 자신보다 긴 문자열에서 공통된 단어가 있는지 찾는 isUnique함수 선언
  5. answer 반환
function solution(words) {
  let answer = 0;
  let len = words.length;
  words.sort((a, b) => a.length - b.length);
  for (let i = 0; i < len - 1; i++) {
    for (let j = i + 1; j < len; j++) {
      if (isUnique(words[i], words[j])) {
        let tmp = words[i].length + words[j].length;
        answer = Math.max(answer, tmp);
      }
    }
  }
  function isUnique(short, long) {
    for (let x of short) {
      if (long.indexOf(x) !== -1) return false;
    }
    return true;
  }
  return answer;
}

회문문자열2

  1. s문자열을 카운팅
  2. 카운팅한 정보를 담은 객체를 내림차순으로 정렬
  3. true일때 동안 반복하는 while구문 생성
  4. 만약 그냥 회문문자열이라면 'YES' 반환
  5. 문자열 내에서 가장많은 문자를 인덱싱한 값을 key_idx에 할당(모두 찾고 끝나면 break)
  6. 인덱싱한 값을 제외한 값들을 슬라이싱해서 word 변수에 할당 후 회문이면 'YES' 반환
  7. 변화없이 while구문이 끝나면 'NO' 반환
function solution(s) {
  let answer = "NO";
  let obj = {};
  s.split("").forEach((e) => {
    obj[e] ? (obj[e] += 1) : (obj[e] = 1);
  });
  const maxArr = Object.entries(obj).sort(([, a], [, b]) => b - a)[0][0];
  let idx = 0;
  while (true) {
    if (s === s.split("").reverse().join("")) return (answer = "YES");
    let key_idx = s.indexOf(maxArr, idx);
    if (key_idx === -1) break;
    let word = s.slice(0, key_idx) + s.slice(key_idx + 1, s.length);
    word === word.split("").reverse().join("") ? (answer = "YES") : false;
    idx = key_idx + 1;
  }
  return answer;
}

학급회장

  1. Map을 이용한 카운팅
  2. max에 가장 안전한 작은값 할당
  3. 맵 객체를 반복문으로 돌며 최대값 반환
function solution(s) {
  let answer;
  let obj = new Map();
  for (let e of s) {
    obj.set(e, obj.get(e) + 1 || 1);
  }
  let max = Number.MIN_SAFE_INTEGER;
  for (let [key, val] of obj) {
    if (val > max) {
      max = val;
      answer = key;
    }
  }
  return answer;
}

아나그램

  1. 애초에 s1과 s2문자열의 길이가 다르다면 'NO' 반환
  2. Map객체로 s1문자열 카운팅
  3. s2 문자열을 돌며 Map 객체에 s2문자열의 문자가 없거나 0이면 'NO' 반환
  4. 반복문 내에서 s2문자열 내의 문자가 있을때마다 -1
  5. 모두 무사히 지나오면 'YES' 반환
function solution(s1, s2) {
  if (s1.length !== s2.length) return "NO";
  let obj = new Map();
  for (let x of s1) {
    obj.set(x, obj.get(x) + 1 || 1);
  }
  for (let x of s2) {
    if (!obj.has(x) || obj.get(x) === 0) return "NO";
    obj.set(x, obj.get(x) - 1);
  }
  return "YES";
}

문자열 구분하기

  1. Map 객체 생성
  2. words배열의 첫 문자열의 길이만큼 반복문을 돈다.
  3. flag 선언
  4. words배열의 길이만큼 반복문을 돌며 i까지 slicing한 값을 x에 할당
  5. Map객체에 x가 있으면 flag를 false로 바꾼후 break
  6. 반복문 끝마다 Map 객체에 1할당
  7. words배열만큼 도는 반복문을 탈출한 뒤 flag가 true면 break
  8. answer에 i+1값을 할당 후 반환
function solution(words) {
  let answer, i;
  let obj = new Map();
  for (i = 0; i < words[0].length; i++) {
    let flag = true;
    for (let j = 0; j < words.length; j++) {
      let x = words[j].substring(0, i + 1);
      if (obj.has(x)) {
        flag = false;
        break;
      }
      obj.set(x, 1);
    }
    if (flag) break;
  }
  answer = i + 1;
  return answer;
}
profile
프론트엔드 개발자

0개의 댓글