반응형

문제 1

sameFrequency 라는 함수를 작성하세요. 두 개의 양의 정수가 주어졌을 때, 두 숫자의 자릿수가 같은 빈도를 갖는지 구합니다.

 

여러분의 솔루션은 반드시 다음과 같은 복잡성을 가져야 합니다.

 

Time: O(N)

 

예시

sameFrequency(182, 281); // true
sameFrequency(34, 14); // false
sameFrequency(3589578, 5879385); // true
sameFrequency(22, 222); // false

 

 

정답

더보기
function sameFrequency(num1, num2) {
  // 빈도수를 담아둘 객체
  const frequency1 = {};
  const frequency2 = {};

  // string화
  const str1 = num1.toString();
  const str2 = num2.toString();

  const str1Length = str1.length;
  const str2Length = str2.length;

  // 길이가 같지 않다면 빈도수가 다름
  if (str1Length !== str2Length) {
    return false;
  }

  // 각 문자별로 객체에 빈도수를 저장
  for (let i = 0; i < str1Length; i++) {
    const s = str1[i];
    frequency1[s] = (frequency1[s] || 0) + 1;
  }
  for (let i = 0; i < str2Length; i++) {
    const s = str2[i];
    frequency2[s] = (frequency2[s] || 0) + 1;
  }

  for (let t in frequency1) {
    if (frequency2[t] !== frequency1[t]) {
      return false;
    }
  }

  return true;
}

 

 

문제 2

가변적인 수의 인수(a variable number of arguments)를 받아들이고 전달된 인자 중 중복이 있는지 확인하는 areThereDuplicates라는 함수를 구현합니다.  빈도 카운터 패턴 또는 다중 포인터 패턴을 사용하여 이 문제를 해결할 수 있습니다.

 

Time - O(n)

Space - O(n)

 

예시

areThereDuplicates(1, 2, 3); // false
areThereDuplicates(1, 2, 2); // true
areThereDuplicates('a', 'b', 'c', 'a'); // true

 

정답

더보기
function areThereDuplicates(...arr) {
  // 갯수를 담아둘 객체를 생성
  const obj = {};

  // 반복문을 돌면서 하나씩 저장
  for (let i = 0; i < arr.length; i++) {
    const current = arr[i];
    // 이미 객체가 있는 경우 return ture
    if (obj[current]) {
      return true;
    }
    obj[current] = (obj[current] || 0) + 1;
  }
  // 마지막에 도달한 경우 return false
  return false;
}

 

문제 3

averagePair라는 함수를 작성합니다. 정렬된 정수 배열과 목표 평균이 주어졌을 때, 배열에 쌍의 평균이 목표 평균과 같은 값의 쌍이 있는지 확인합니다. 목표 평균과 일치하는 쌍이 두 개 이상 있을 수 있습니다.

 

Time: O(N)

Space: O(1)

 

예시

averagePair([1,2,3],2.5) // true
averagePair([1,3,3,5,6,7,10,12,19],8) // true
averagePair([-1,0,3,4,5,6], 4.1) // false
averagePair([],4) // false

 

정답

더보기
function averagePair(arr, avg) {
  //   양쪽에 포인터를 하나씩 둠
  let left = 0;
  let right = arr.length - 1;
  //   평균의 값을 2배 한 값을 구함.
  const avg2 = avg * 2;
  // 포인터 왼쪽이 작아질때까지 반복문을 돔.
  while (left < right) {
    // 양 포인터의 값을 합함.
    const sum = arr[left] + arr[right];
    // 합이 같은 경우 정답
    if (sum === avg2) {
      return true;
    } else if (sum < avg2) {
      // 만약 포인터의 값을 합한게 2배 값보다 작다면 왼쪽 포인터를 늘림.
      left++;
    } else {
      // 만약 포인터의 값을 합한게 2배 값보다 크다면 오른쪽 포인터를 줄임.
      right--;
    }
  }
  // 전부 반복했는데 정답이 없는 경우
  return false;
}

 

문제 4

두 문자열을 받아 첫 번째 문자열의 문자가 두 번째 문자열의 문자의 일부에 포함되는지 확인하는 isSubsequence라는 함수를 작성합니다. 즉, 이 함수는 첫 번째 문자열의 문자가 순서가 바뀌지 않고 두 번째 문자열의 어딘가에 나타나는지 확인해야 합니다.

 

Time: O(N + M)

Space: O(1)


예시

isSubsequence('hello', 'hello world'); // true
isSubsequence('sing', 'sting'); // true
isSubsequence('abc', 'abracadabra'); // true
isSubsequence('abc', 'acb'); // false (order matters)

 

 

정답

더보기
function isSubsequence(str1, str2) {
  let i = 0;
  let j = 0;
  if (!str1) {
      return true
      
  };
  while (j < str2.length) {
    if (str2[j] === str1[i]) {
        i++
    };
    if (i === str1.length) {
        return true
        
    };
    j++;
  }
  return false;
}

 

 

문제 5

정수의 배열과 숫자가 주어졌을 때, 함수에 전달된 숫자의 길이를 가진 하위 배열의 최대 합을 구하는 maxSubarraySum이라는 함수를 작성하세요.

 

하위 배열은 원래 배열의 연속적인 요소로 구성되어야 한다는 점에 유의하세요. 아래 첫 번째 예제에서 [100, 200, 300]은 원래 배열의 하위 배열이지만 [100, 300]은 그렇지 않습니다.

 

Time: O(N)

Space: O(1)

 

예시

maxSubarraySum([100,200,300,400], 2) // 700
maxSubarraySum([1,4,2,10,23,3,1,0,20], 4)  // 39 
maxSubarraySum([-3,4,0,-2,6,-1], 2) // 5
maxSubarraySum([3,-2,7,-4,1,-1,4,-2,1],2) // 5
maxSubarraySum([2,3], 3) // null

 

정답

더보기
function maxSubarraySum(arr, num) {
  // 최대 합 선언
  let maxSum = 0;
  // 임시 합
  let tempSum = 0;
  // num보다 arr의 길이가 작으면  null return
  if (arr.length < num) {
    return null;
  }

  // 첫번째 임시 합을 구함
  for (let i = 0; i < num; i++) {
    tempSum += arr[i];
  }

  // 현재 최대 합은 첫번째 합
  maxSum = tempSum;

  for (let i = num; i < arr.length; i++) {
    // 반복문을 돌며 앞에 숫자를 빼고 뒤에 숫자를 더함.
    tempSum = tempSum - arr[i - num] + arr[i];
    // 둘 중 더 큰 값이 maxSum
    maxSum = Math.max(maxSum, tempSum);
  }

  return maxSum;
}

 

문제 6

 

양수 배열과 양수라는 두 개의 매개 변수를 받아들이는 minSubArrayLen이라는 함수를 작성하세요.

이 함수는 합이 함수에 전달된 정수보다 크거나 같은 인접한 하위 배열의 최소 길이를 반환해야 합니다. 값이 없는 경우 0을 반환합니다.

 

Time: O(n)

Space: O(1)


예시

minSubArrayLen([2,3,1,2,4,3], 7) // 2 -> because [4,3] is the smallest subarray
minSubArrayLen([2,1,6,5,4], 9) // 2 -> because [5,4] is the smallest subarray
minSubArrayLen([3,1,7,11,2,9,8,21,62,33,19], 52) // 1 -> because [62] is greater than 52
minSubArrayLen([1,4,16,22,5,7,8,9,10],39) // 3
minSubArrayLen([1,4,16,22,5,7,8,9,10],55) // 5
minSubArrayLen([4, 3, 3, 8, 1, 2, 3], 11) // 2
minSubArrayLen([1,4,16,22,5,7,8,9,10],95) // 0

 

정답

더보기
const minSubArrayLen = (nums, sum) => {
  // 전체값, 시작 인덱스 끝 인덱스, 최소 길이 변수 초기화
  let total = 0;
  let start = 0;
  let end = 0;
  let minLen = Infinity;

  // start가 배열의 길이보다 작은 동안 루프를 반복
  while (start < nums.length) {
    // 현재 윈도우의 합이 sum보다 작고 end가 배열의 끝에 도달하지 않은 경우
    // end를 증가시키면서 윈도우를 확장하고 total에 nums[end] 값을 더함
    if (total < sum && end < nums.length) {
      total += nums[end];
      end++;
    } else if (total >= sum) {
      // 현재 윈도우의 합이 sum보다 크거나 같은 경우, 최소 길이를 계산하여 minLen을 업데이트한다.
      // 그런 다음, start를 증가시키면서 윈도우를 축소하고 total에서 nums[start] 값을 뺀다.
      minLen = Math.min(minLen, end - start);
      total -= nums[start];
      start++;
    }
    // current total less than required total but we reach the end, need this or else we'll be in an infinite loop
    else {
      break;
    }
  }

  return minLen === Infinity ? 0 : minLen;
};

 

 

문제 7

문자열을 받아 모든 고유 문자가 포함된 가장 긴 하위 문자열의 길이를 반환하는 findLongestSubstring이라는 함수를 작성하세요.

 

Time: O(n)

 

예시

findLongestSubstring('') // 0
findLongestSubstring('rithmschool') // 7
findLongestSubstring('thisisawesome') // 6
findLongestSubstring('thecatinthehat') // 7
findLongestSubstring('bbbbbb') // 1
findLongestSubstring('longestsubstring') // 8
findLongestSubstring('thisishowwedoit') // 6

 

정답

더보기
function findLongestSubstring(str) {
  let longest = 0;
  let seen = {};
  let start = 0;
 
  for (let i = 0; i < str.length; i++) {
    let char = str[i];
    if (seen[char]) {
      start = Math.max(start, seen[char]);
    }
    longest = Math.max(longest, i - start + 1);
    seen[char] = i + 1;
  }
  return longest;
}
반응형

'Algorithm > Theory' 카테고리의 다른 글

재귀 연습 문제  (0) 2024.07.09
재귀 (Recursion)  (0) 2024.07.08
문제 해결 패턴  (0) 2024.06.28
문제 해결 접근법  (0) 2024.06.27
Javascript에서 배열과 오브젝트의 빅오 (Big - O)  (0) 2024.06.26
얼은펭귄