algorithms Flashcards

1
Q

what is the difference between permutations and combinations?

A

permutation - order matters

combination - order does not matter

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
2
Q

Given a collection of distinct integers, return all possible permutations.

Example:

Input: [1,2,3]
Output:
[
  [1,2,3],
  [1,3,2],
  [2,1,3],
  [2,3,1],
  [3,1,2],
  [3,2,1]
]
A
var permute = function(choices, temp = [], permutations = []) {
    if(choices.length === 0){
      permutations.push([...temp]);
    } 
for(let i = 0; i < choices.length; i++){
    let newChoices = choices.filter((choice, index) => index !== i)
    temp.push(choices[i])
    permute(newChoices, temp, permutations)
    temp.pop()
}

return permutations };
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
3
Q

What is a Bottom-Up approach?

A

The bottom-up approach is often the most intuitive. We start with knowing how to solve the problem
for a simple case, like a list with only one element. Then we figure out how to solve the problem for two
elements, then for three elements, and so on. The key here is to think about how you can build the solution
for one case off of the previous case (or multiple previous cases).

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
4
Q

What is a Top-down approach?

A

The top-down approach can be more complex since it’s less concrete. But sometimes, it’s the best way to
think about the problem.
In these problems, we think about how we can divide the problem for case N into subproblems.
Be careful of overlap between the cases.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
5
Q

Half-and-Half Approach

A

In addition to top-down and bottom-up approaches, it’s often effective to divide the data set in half.
For example, binary search works with a “half-and-half” approach. When we look for an element in a sorted
array, we first figure out which half of the array contains the value. Then we recurse and search for it in that
half.
Merge sort is also a “half-and-half” approach. We sort each half of the array and then merge together the
sorted halves.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
6
Q

Dynamic programming

A

Dynamic programming is mostly just a matter of taking a recursive algorithm and finding the overlapping
subproblems (that is, the repeated calls). You then cache those results for future recursive calls.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
7
Q

How do you find the nth Fibonacci?

A
- top down
memo = []
function fib(n) {
if (memo[n]) return memo[n]
let f
if(n <=2) f = 1
else f  = fib(n-1) + fib(n-2)
memo[n] = f
return f 
}
-bottom up
fib = []
function(n){
for(let I = 0; I < = n; I++){
if(I <=2) fib[i] = 1
else fib[I]= fib[I-1] + fib[I-2]
}
return fib[n]
}
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
8
Q

What is the benefit of using memoization in a top down approach in recursion

A

it stores computations in a cache and removes the need of making a computation that we made in a previous tree

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
9
Q

5 steps in dynamic programming

A
  1. define subproblems
  2. guess (part of the solution)
  3. relate subproblem solutions
  4. recurse & memoize OR use loops bottom up approach
  5. solve the original problem
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
10
Q

Given a set of distinct integers, nums, return all possible subsets (the power set).

Note: The solution set must not contain duplicate subsets.

Example:

Input: nums = [1,2,3]
Output:
[
  [3],
  [1],
  [2],
  [1,2,3],
  [1,3],
  [2,3],
  [1,2],
  []
]
A
var subsets = function(nums) {
    const subsets = [];
    permute(0, nums, [], subsets);
    return subsets;
};

function permute(index, nums, current, subsets){
subsets.push(current.slice(0))
for(let i = index; i < nums.length; i++){
current.push(nums[i]);
permute(i+1,nums,current,subsets);
current.pop();
}
}

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
11
Q

Implement tower of hanoi

A

var hanoi = function(disks, source, destination, buffer) {
if(disks === 1){
destination.push(source.pop());
} else {
hanoi(disks-1, source, buffer,destination);
destination.push(source.pop());
hanoi(disks-1, buffer, destination, source);
}
}

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
12
Q

Given a string, determine if a permutation of the string could form a palindrome.

A
var isAnagram = function(s) {
  let odds = 0;
  const store = {}
  for(let i = 0; i < s.length; i++){
    store[s[i]] === undefined ? store[s[i]] = 1 : store[s[i]]++
    if(store[s[i]] % 2 !== 0) {
       odds++
     } else {
      odds--
       }
  }

return odds < 2
};

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
13
Q

You are given an n x n 2D matrix representing an image.

Rotate the image by 90 degrees (clockwise).

Note:

You have to rotate the image in-place, which means you have to modify the input 2D matrix directly. DO NOT allocate another 2D matrix and do the rotation.

Example 1:

Given input matrix = 
[
  [1,2,3],
  [4,5,6],
  [7,8,9]
],
rotate the input matrix in-place such that it becomes:
[
  [7,4,1],
  [8,5,2],
  [9,6,3]
]
A
var rotate = function(matrix) {
    if(matrix.length === 0 || matrix.length!==matrix[0].length) return false
    const len = matrix.length
    for(let layer = 0; layer < len/2; layer++){
        let first = layer;
        let last = len - 1 - layer;
        for(let i = first; i < last; i++){
            let offset = i - first;
            let top = matrix[first][i];
            // left -> top
            matrix[first][i] = matrix[last-offset][first];
            // bottom -> left
            matrix[last-offset][first] = matrix[last][last-offset];
            //right -> bottom
            matrix[last][last-offset] =matrix[i][last];
            // top -> right
            matrix[i][last] = top; // right
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
14
Q

What is an in place algorithm

A

In computer science, an in-place algorithm is an algorithm which transforms input using no auxiliary data structure. However a small amount of extra storage space is allowed for auxiliary variables. The input is usually overwritten by the output as the algorithm executes. In-place algorithm updates input sequence only through replacement or swapping of elements

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
15
Q

Given a m x n matrix, if an element is 0, set its entire row and column to 0. Do it in-place.

Example 1:

Input: 
[
  [1,1,1],
  [1,0,1],
  [1,1,1]
]
Output: 
[
  [1,0,1],
  [0,0,0],
  [1,0,1]
]
Example 2:
Input: 
[
  [0,1,2,0],
  [3,4,5,2],
  [1,3,1,5]
]
Output: 
[
  [0,0,0,0],
  [0,4,5,0],
  [0,3,1,0]
]
A
var setZeroes = function(matrix) {
    let isCol = false;
    let R = matrix.length;
    let C = matrix[0].length;
for (let i = 0; i < R; i++) {
      // Since first cell for both first row and first column is the same i.e. matrix[0][0]
      // We can use an additional variable for either the first row/column.
      // For this solution we are using an additional variable for the first column
      // and using matrix[0][0] for the first row.
      if (matrix[i][0] == 0) {
        isCol = true;
      }
      for (let j = 1; j < C; j++) {
        // If an element is zero, we set the first element of the corresponding row and column to 0
        if (matrix[i][j] == 0) {
          matrix[0][j] = 0;
          matrix[i][0] = 0;
        }
      }
    }
    // Iterate over the array once again and using the first row and first column, update the elements.
    for (let i = 1; i < R; i++) {
      for (let j = 1; j < C; j++) {
        if (matrix[i][0] == 0 || matrix[0][j] == 0) {
          matrix[i][j] = 0;
        }
      }
    }
    // See if the first row needs to be set to zero as well
    if (matrix[0][0] == 0) {
      for (let j = 0; j < C; j++) {
        matrix[0][j] = 0;
      }
    }
    // See if the first column needs to be set to zero as well
    if (isCol) {
      for (let i = 0; i < R; i++) {
        matrix[i][0] = 0;
      }
    }
};
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
16
Q

Given a string s, find the longest palindromic substring in s. You may assume that the maximum length of s is 1000.

Example 1:

Input: “babad”
Output: “bab”
Note: “aba” is also a valid answer.
Example 2:

Input: “cbbd”
Output: “bb”

A
var longestPalindrome = function (s) {
    if (s===null || s.length < 1) return "";
    let start = 0, end = 0;
    for (let i = 0; i < s.length; i++) {
        let len1 = expandAroundCenter(s, i, i);
        let len2 = expandAroundCenter(s, i, i + 1);
        let len = Math.max(len1, len2);
        if (len > end - start) {
            start = i - Math.floor((len - 1) / 2);
            end = i + Math.floor(len / 2);
        }
    }
    return s.substring(start, end + 1);
}
function expandAroundCenter( s,  left,  right) {
    if(s === null || left > right) return 0;
    while (left >= 0 &amp;&amp; right < s.length &amp;&amp; s.charAt(left) == s.charAt(right)) {
        left--;
        right++;
    }
    return right - left - 1;
}
17
Q

Given an array nums of n integers where n > 1, return an array output such that output[i] is equal to the product of all the elements of nums except nums[i].

Example:

Input: [1,2,3,4]
Output: [24,12,8,6]
Note: Please solve it without division and in O(n).

Follow up:
Could you solve it with constant space complexity? (The output array does not count as extra space for the purpose of space complexity analysis.)

A

var productExceptSelf = function(nums) {

        // The length of the input array 
        let length = nums.length;
        // Final answer array to be returned
        let answer = [];
        // answer[i] contains the product of all the elements to the left
        // Note: for the element at index '0', there are no elements to the left,
        // so the answer[0] would be 1
        answer[0] = 1;
        for (let i = 1; i < length; i++) {
            // answer[i - 1] already contains the product of elements to the left of 'i - 1'
            // Simply multiplying it with nums[i - 1] would give the product of all 
            // elements to the left of index 'i'
            answer[i] = nums[i - 1] * answer[i - 1];
        }
        // R contains the product of all the elements to the right
        // Note: for the element at index 'length - 1', there are no elements to the right,
        // so the R would be 1
        let R = 1;
        for (let i = length - 1; i >= 0; i--) {
            // For the index 'i', R would contain the 
            // product of all elements to the right. We update R accordingly
            answer[i] = answer[i] * R;
            R *= nums[i];
        }
    return answer;
}
18
Q

Say you have an array for which the ith element is the price of a given stock on day i.

If you were only permitted to complete at most one transaction (i.e., buy one and sell one share of the stock), design an algorithm to find the maximum profit.

Note that you cannot sell a stock before you buy one.

Example 1:

Input: [7,1,5,3,6,4]
Output: 5
Explanation: Buy on day 2 (price = 1) and sell on day 5 (price = 6), profit = 6-1 = 5.
Not 7-1 = 6, as selling price needs to be larger than buying price.
Example 2:

Input: [7,6,4,3,1]
Output: 0
Explanation: In this case, no transaction is done, i.e. max profit = 0.

A
var maxProfit = function(prices) {
    let min = prices[0]
    let output = 0;
    for(let i=1; i < prices.length;i++){
        const cur = prices[i]
        const diff = cur - min
        if(cur < min) min = cur
        if(diff > output) output = diff  
    }
    return output;
};
19
Q

Given an integer array nums, find the contiguous subarray (containing at least one number) which has the largest sum and return its sum.

Example:

Input: [-2,1,-3,4,-1,2,1,-5,4],
Output: 6
Explanation: [4,-1,2,1] has the largest sum = 6.

A
function maxSubArray(A) {
  var prev = 0;
  var max = -Number.MAX_VALUE;
  for (var i = 0; i < A.length; i++) {
    prev = Math.max(prev + A[i], A[i]);
    max = Math.max(max, prev);
  }
  return max;
}
20
Q

What is the main quality of a greedy algorithm?

A

Greedy algorithms make the best choice at each decision without looking ahead.

21
Q

Given an integer array nums, find the contiguous subarray within an array (containing at least one number) which has the largest product.

Example 1:

Input: [2,3,-2,4]
Output: 6
Explanation: [2,3] has the largest product 6.
Example 2:

Input: [-2,0,-1]
Output: 0
Explanation: The result cannot be 2, because [-2,-1] is not a subarray.

A
var maxProduct = function(nums) {
    let currentMax = nums[0];
  let currentMin = nums[0];
  let finalMax = nums[0];
  for(let i = 1; i < nums.length; i++){
    let temp = currentMax
    currentMax = Math.max(Math.max(currentMax * nums[i], currentMin*nums[i]), nums[i])
    currentMin = Math.min(Math.min(temp * nums[i], currentMin*nums[i]), nums[i])
    if(currentMax > finalMax){
      finalMax = currentMax;
    }
  }

return finalMax;

};

22
Q

Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand.

(i.e., [0,1,2,4,5,6,7] might become [4,5,6,7,0,1,2]).

Find the minimum element.

You may assume no duplicate exists in the array.

Example 1:

Input: [3,4,5,1,2]
Output: 1
Example 2:

Input: [4,5,6,7,0,1,2]
Output: 0

A
var findMin = function(nums) {
    // If the list has just one element then return that element.
    if (nums.length == 1) {
      return nums[0];
    }
    // initializing left and right pointers.
    let left = 0, right = nums.length - 1;
    // if the last element is greater than the first element then there is no rotation.
    // e.g. 1 < 2 < 3 < 4 < 5 < 7. Already sorted array.
    // Hence the smallest element is first element. A[0]
    if (nums[right] > nums[0]) {
      return nums[0];
    }
    // Binary search way
    while (right >= left) {
      // Find the mid element
      let mid = left + Math.floor((right - left) / 2);
      // if the mid element is greater than its next element then mid+1 element is the smallest
      // This point would be the point of change. From higher to lower value.
      if (nums[mid] > nums[mid + 1]) {
        return nums[mid + 1];
      }
      // if the mid element is lesser than its previous element then mid element is the smallest
      if (nums[mid - 1] > nums[mid]) {
        return nums[mid];
      }
      // if the mid elements value is greater than the 0th element this means
      // the least value is still somewhere to the right as we are still dealing with elements
      // greater than nums[0]
      if (nums[mid] > nums[0]) {
        left = mid + 1;
      } else {
        // if nums[0] is greater than the mid value then this means the smallest value is somewhere to
        // the left
        right = mid - 1;
      }
    }
    return -1;

};

23
Q

Given an array nums of n integers, are there elements a, b, c in nums such that a + b + c = 0? Find all unique triplets in the array which gives the sum of zero.

Note:

The solution set must not contain duplicate triplets.

Example:

Given array nums = [-1, 0, 1, 2, -1, -4],

A solution set is:
[
  [-1, 0, 1],
  [-1, -1, 2]
]
A
function threeSum(nums) {
	const results = []
	// obviously irrelevant if we don't have at least 3 numbers to play with!
	if (nums.length < 3) return results
	// having the numbers in ascending order will make this problem much easier.
	// also, knowing the overall problem  will take at least O(N^2) time, we can
	// afford the O(NlogN) sort operation
	nums = nums.sort((a, b) => a - b)
    // if the question asks us for a custom target, we can control it here
	let target = 0
	for (let i = 0; i < nums.length - 2; i++) {
		// `i` represents the "left" most number in our sorted set.
		// once this number hits 0, there's no need to go further since
		// positive numbers cannot sum to a negative number
		if (nums[i] > target) break
		// we don't want repeats, so skip numbers we've already seen
		if (i > 0 &amp;&amp; nums[i] === nums[i - 1]) continue
		// `j` represents the "middle" element between `i` and `k`.
		// we will increment this up through the array while `i` and `k`
		// are anchored to their positions. we will decrement `k` for
		// for each pass through the array, and finally increment `i`
		// once `j` and `k` meet.
		let j = i + 1
		// `k` represents the "right" most element
		let k = nums.length - 1
		// to summarize our setup, we have `i` that starts at the beginning,
		// `k` that starts at the end, and `j` that races in between the two.
		//
		// note that `i` is controlled by our outer for-loop and will move the slowest.
		// in the meantime, `j` and `k` will take turns inching towards each other depending
		// on some logic we'll set up below. once they collide, `i` will be incremented up
		// and we'll repeat the process.
		while (j < k) {
			let sum = nums[i] + nums[j] + nums[k]
			// if we find the target sum, increment `j` and decrement `k` for
			// other potential combos where `i` is the anchor
			if (sum === target) {
				// store the valid threesum
				results.push([nums[i], nums[j], nums[k]])
				// this is important! we need to continue to increment `j` and decrement `k`
				// as long as those values are duplicated. in other words, we wanna skip values
				// we've already seen. otherwise, an input array of [-2,0,0,2,2] would result in
				// [[-2,0,2], [-2,0,2]].
				//
				// (i'm not a fan of this part because we're doing a while loop as we're
				// already inside of another while loop...)
				while (nums[j] === nums[j + 1]) j++
				while (nums[k] === nums[k - 1]) k--
			// finally, we need to actually move `j` forward and `k` backward to the
			// next unique elements. the previous while loops will not handle this.
			j++
			k--
			// if the sum is too small, increment `j` to get closer to the target
			} else if (sum < target) {
				j++
			// if the sum is too large, decrement `k` to get closer to the target
			} else { // (sum > target)
				k--
			}
		}
	}
return results };
24
Q

Implement an isAnagram method in java

A

static boolean isAnagram(String a, String b) {
if(a.length() != b.length()) return false;
int c[] = new int[26], d[] = new int[26] ;
a = a.toUpperCase();
b = b.toUpperCase();
for(int i=0; i