5. Longest Palindromic Substring

Description:

https://leetcode.com/problems/longest-palindromic-substring/#/description

Boundary:

No

Algorithm:

  1. DP (Easy to understand, but slow. Time complexity O(n^2) )
  2. Manacher (fast, time complexity O(n)) http://www.cnblogs.com/grandyang/p/4475985.html

Code:

DP:

class Solution {
public:
string longestPalindrome(string s) {
int dp[s.size()][s.size()];
int left = 0,right = 0, len = 0;

for (int i = 0; i < s.size();i++)
{
for (int j = 0; j < i; j++)
{
dp[j][i] = s[i] == s[j] && (i-j < 2 || dp[j + 1][i – 1] == 1);
if(dp[j][i] && len < i – j + 1)
{
left = j;
right = i;
len = i – j + 1;
}
}
dp[i][i] = 1;
}
return s.substr(left, right – left + 1);
}
};

 

Manacher:

class Solution {
public:
// Transform S into T.
// For example, S = “abba”, T = “^#a#b#b#a#$”.
// ^ and $ signs are sentinels appended to each end to avoid bounds checking
string preProcess(string s) {
int n = s.length();
if (n == 0) return “^$”;
string ret = “^”;
for (int i = 0; i < n; i++) ret += “#” + s.substr(i, 1);
ret += “#$”;
return ret;
}
string longestPalindrome(string s) {
string T = preProcess(s);
const int n = T.length();
// 以T[i] 为中心,向左/右扩张的长度,不包含T[i] 自己,
// 因此P[i] 是源字符串中回文串的长度
vector<int> P = vector<int>(n,-1);
int C = 0, R = 0;
for (int i = 1; i < n – 1; i++) {
int i_mirror = 2 * C – i; // equals to i’ = C – (i-C)
P[i] = (R > i) ? min(R – i, P[i_mirror]) : 0;
// Attempt to expand palindrome centered at i
while (T[i + 1 + P[i]] == T[i – 1 – P[i]])
P[i]++;
// If palindrome centered at i expand past R,
// adjust center based on expanded palindrome.
if (i + P[i] > R) {
C = i;
R = i + P[i];
}
}
// Find the maximum element in P.
int max_len = 0;
int center_index = 0;
for (int i = 1; i < n – 1; i++) {
if (P[i] > max_len) {
max_len = P[i];
center_index = i;
}
}
return s.substr((center_index – 1 – max_len) / 2, max_len);
}
};

 

Tips:

  1. Get a substring of a string: s.substr(start, LengthOfString);

06/13/2017

Research:

  • Measure time of the three scenes (KFR, Origin, GausOptFlow).
  • Origin: 32.2 fps
  • KFR: 20.4 fps
  • GausOptFlow: 20.2 fps

LeetCode:

  • 4. Median of Two Sorted Arrays
    • Cannot use concatinate + sort because the time complexity goes beyond log(m+n).
    • If time complexity is log(*), consider about dichotomy.
  • 5. Longest Palindromic Substring
    • Manacher
    • DP
    • s.substr(start, length) (can also use this to read the ith element in string in string format, you know, s[i] is char)

Parallel Computing Study:

  • Finish watching video of Lesson2

Guitar:

  • practice.

Others:

Presentation next Monday:

  • Prepare the PPT

06/12/2017

Research:

  • Merge the three scenes (KFR, Origin, GausOptFLow) into one program.
  • Tried to measure time: have problem (the time are all the same)
  • Tried to export mesh but failed.

LeetCode:

  • 2. Add Two Numbers
    • Cannot use list2num/num2list (overflow), should use full adder algorithm.
  • 3. Longest Substring Without Repeating Characters
    • “dvdf”

Parallel Computing Study:

  • Finish watching video of Lesson2

733Code->C++:

  • Panorama Maker

Guitar:

  • practice.

Others:

Presentation next Monday:

  • Prepare the PPT

3. Longest Substring Without Repeating Characters

Description:

https://leetcode.com/problems/longest-substring-without-repeating-characters/#/description

Boundary:

when s.size() ==0

Algorithm:

Initially, I just thought about discard the previous longest string and calculate the new string.

However, we cannot discard the whole previous string, the elements may be useful in the following string, such as “dvdf” ‘s result is 3 rather than 2.

Code:

class Solution {
public:
int lengthOfLongestSubstring(string s) {
if (!s.size()) return 0;
string cur = “”;
string pre = “”;
for (int k = 0; k < s.size();k++)
{
while (cur.find(s[k]) < cur.npos)
{
if (cur.size() >= pre.size())
pre = cur;
cur.erase(cur.begin());
}
cur += s[k];
}
if (cur.size() < pre.size())
return pre.size();
else
return cur.size();
}
};

Tip:

Beats 65.54%. The time complexity is O(n).

2. Add Two Numbers

Description:

https://leetcode.com/problems/add-two-numbers/#/description

Boundary:

When one is NULL while the other is not

Algorithm:

Initially, I want to implement list2int and int2lis, however, I find that when the number gets overflow, it will get the wrong result for list2int.

Therefore, the problem should be finished as done for full adder.

When (l1 != NULL && l2 != NULL)

sum = l1 -> val+ l2 -> val + carry;

when (one is NULL and the other not)

sum = (l1 or l2) -> val + carry;

finally, if (carry), add carry to the end of list.

Code:

class Solution {
public:
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
int carry = 0;
ListNode* tmp;
ListNode *start = NULL;
ListNode *node = start;
int n1, n2, sum;
while (l1 != NULL || l2 != NULL)
{
if (l1 == NULL)
{
n1 = 0;
}
else
{
n1 = l1->val;
l1 = l1->next;
}
if (l2 == NULL)
{
n2 = 0;
}
else
{
n2 = l2->val;
l2 = l2->next;
}
sum = n1 + n2 + carry;
carry = sum / 10;

if (start == NULL)
{
start = new ListNode(sum % 10);
node = start;
}
else
{
tmp = new ListNode(sum % 10);
node->next = tmp;
node = tmp;
}
}
if (carry)
{
tmp = new ListNode(carry);
node->next = tmp;
}
return start;
}
};

Tip:

My code is identical to the example code of the fastest. However, the fastest is 26ms while mine is 55ms! Why???

566. Reshape the Matrix

Description:

https://leetcode.com/problems/reshape-the-matrix/#/description

Boundary:

r * c == r’ * c’?

Algorithm:

Store the data in one dim vector and evaluate the new r*c matrix

Code:

class Solution {
public:
vector<vector<int>> matrixReshape(vector<vector<int>>& nums, int r, int c) {
int m = nums.size();
int n = nums[0].size();

if (r * c != m * n)
return nums;

vector<int> nums_all;
vector<vector<int>> nums_new = vector<vector<int>>(r, vector<int>(c, -1));
for (int k = 0; k < m; k++)
nums_all.insert(nums_all.end(), nums[k].begin(), nums[k].end());
int count = 0;
for (int i = 0; i < r; i++)
for (int j = 0; j < c; j++)
nums_new[i][j] = nums_all[count++];
return nums_new;
}
};

Time:

 

500. Keyboard Row

Description:

https://leetcode.com/problems/keyboard-row/#/description

Boundary:

NO

Algorithm:

Not difficult. Use:

str.find() < str.nops

Code:

class Solution {
public:
vector<string> findWords(vector<string>& words) {
vector<string> result;
for (int k = 0; k < words.size(); k++)
{
if (line1_Big.find(words[k][0]) < line1_Big.size() || line1_Sml.find(words[k][0]) < line1_Sml.size())
{
if (ifExist(words[k], line1_Big, line1_Sml))
result.push_back(words[k]);
}
else if (line2_Big.find(words[k][0]) < line2_Big.size() || line2_Sml.find(words[k][0]) < line2_Sml.size())
{
if (ifExist(words[k], line2_Big, line2_Sml))
result.push_back(words[k]);
}
else
{
if (ifExist(words[k], line3_Big, line3_Sml))
result.push_back(words[k]);
}

}
return result;
}
private:
string line1_Big = “QWERTYUIOP”;
string line1_Sml = “qwertyuiop”;

string line2_Big = “ASDFGHJKL”;
string line2_Sml = “asdfghjkl”;

string line3_Big = “ZXCVBNM”;
string line3_Sml = “zxcvbnm”;
bool ifExist(string word, string big, string small)
{
for (int i = 1; i < word.size(); i++)
{
if (big.find(word[i]) > big.size() && small.find(word[i]) > small.size())
return false;
}
return true;
}
};

557. Reverse Words in a String III

Description:

https://leetcode.com/submissions/detail/105718837/

Boundary:

No boundary needs to be considered.

Algorithm:

Use a for loop to read the char in the string one by one, record the start and end of each word.

If meets a ‘ ‘, swap poistion and store in an new string.

Code:

class Solution {
public:
string reverseWords(string s) {
string s_new = s;
int counter = 0;
int start = 0;
for (int k = 0; k < s.size();k++)
{
if (s[k] == ‘ ‘)
{
for (int i = start; i < counter; i++)
{
char s1 = s[counter – 1 – (i – start)];
s_new[i] = s1;
}

start = counter + 1;
}
else if (k == s.size() – 1)
{
for (int i = start; i <= counter; i++)
{
char s1 = s[counter – (i – start)];
s_new[i] = s1;
}
}
counter++;
}
return s_new;
}
};

476. Number Complement

Description:

https://leetcode.com/problems/number-complement/#/description

Boundary:

NO

Algorithm:

如果直接~num,C++直接进行补码取反。

因此需要设定mask,然后一位一位操作。

Reference: http://blog.chinaunix.net/uid-25909722-id-2856108.html

C的位操作常常使用使用一个unsigned int变量来作为位容器。

设置特定的位用| (OR);
清除特定的位用&(AND);
取反特定的位用^(XOR);
取反所有的位用~(NOT);

C++中bitset容器来操作位

可以通过to_string()成员函数将容器输出为一个string字符串;
可以通过to_long()成员函数将容器输出到传统的用于C风格的位容器中。

Code:

 

class Solution {
public:
int findComplement(int num) {
unsigned mask = ~0;
while (mask & num) mask <<= 1;
return ~mask & ~num;
}
};