Sunday, September 25, 2016

Problem

Given a string S, find the longest palindromic substring in S. You may assume that the maximum length of S is 1000, and there exists one unique longest palindromic substring.

Examples:

Given "cababade", return "ababa"
Given "gcaack", return "caac"

Solution

This problem is similar to that of the Longest Common Subsequence, and as most should suspect, can be solved using dynamic programming. Because we must consider all possible substrings as a palindrome, we can expect an (n)(n+1)/2=O(n^2) solution. There are quite a few ways to solve this in O(n^2), but the basic idea is that we keep track of all palindromes starting at i, and ending at j. When i==j and the characters at position i and j are equal, the character is a palindrome with itself of length 1. If the characters are equal and i!=j, then either the two same characters are next to each other, or are the beginning and end of a previous palindrome. In both cases we add 2 to account for the length of the character on both ends.

Below is the code for this approach. The loops run from the end of the string to produce a matrix A with the upper triangle containing lengths of palindromes. The maximum palindrome is kept track of and returned.

Sunday, September 4, 2016

Problem

There are two sorted arrays nums1 and nums2 of size m and n respectively.

Find the median of the two sorted arrays. The overall run time complexity should be O(log(m+n)).

Example 1:

nums1 = [1, 3]
nums2 = [2]
The median is 2.0

Example 2:

nums1 = [1, 2]
nums2 = [3, 4]
The median is (2 + 3)/2 = 2.5

Solution

The idea behind this problem is quite simple. To find the median in O(log(n+m)), we need to perform some kind of binary search concurrently on both arrays. The difficulty is in making sure to consider all possible cases. Overall, there is a general case that performs the binary search, and a base case to chose the median among four or less remaining elements. The code below has the different cases commented. The idea is to keep track of how many elements have been removed from each side, and repeatedly split either array in half such that we remove the smaller or larger elements from the left or right side, respectively.

This is certainly not the most clean or efficient solution to this problem as there are many cases that need to be explicitly handled. Another solution is to use a recursive divide and conquer approach where you determine the two array's medians, and then recurse on the halves of the arrays that bring the medians closer (or equal to each other).