2021-04-29 Daily-Challenge

Today I have done Minimum Insertion Steps to Make a String Palindrome and leetcode's April LeetCoding Challenge with cpp.

Minimum Insertion Steps to Make a String Palindrome

Description

Given a string s. In one step you can insert any character at any index of the string.

Return the minimum number of steps to make s palindrome.

A Palindrome String is one that reads the same backward as well as forward.

Example 1:

Input: s = "zzazz"
Output: 0
Explanation: The string "zzazz" is already palindrome we don't need any insertions.

Example 2:

Input: s = "mbadm"
Output: 2
Explanation: String can be "mbdadbm" or "mdbabdm".

Example 3:

Input: s = "leetcode"
Output: 5
Explanation: Inserting 5 characters the string becomes "leetcodocteel".

Example 4:

Input: s = "g"
Output: 0

Example 5:

Input: s = "no"
Output: 1

Constraints:

  • 1 <= s.length <= 500
  • All characters of s are lower case English letters.

Solution

I first write this

class Solution {
  int minInsert(string &s, string &l) {
    int len = s.length();
    int llen = l.length();
    vector<int> dp(len + 1);
    for(int i = 0; i < llen; ++i) {
      int prev = 0;
      for(int j = 0; j < len; ++j) {
        dp[i + 1] = max(prev, dp[i + 1]);
        if(s[j] == l[i]) {
          dp[j + 1] = max(dp[j] + 1, dp[j + 1]);
        }
        prev = dp[j + 1];
      }
    }
    return len + llen - 2 * dp.back();
  }
public:
  int minInsertions(string s) {
    int len = s.length();
    int answer = len - 1;
    for(int i = 1; i < len - 1; ++i) {
      cout << i << ' ';
      string l = s.substr(i);
      string st = s.substr(0, i);
      cout << st << ' ' << l << endl;
      reverse(l.begin(), l.end());
      answer = min(answer, minInsert(st, l));
      l.pop_back();
      answer = min(answer, minInsert(st, l));
    }
    return answer;
  }
};

try to optimize

auto speedup = []() {
  std::ios::sync_with_stdio(false);
  cin.tie(nullptr);
  cout.tie(nullptr);
  return nullptr;
}();
class Solution {
  vector<vector<int>> dp;
  int minInsert(string &s1, string &s2) {
    int len1 = s1.length();
    int len2 = s2.length();
    // cout << "$$$$$$";
    for(int i = 0; i <= len2; ++i) {
      dp[0][i] = 0;
      dp[1][i] = 0;
    }
    for(int i = 0; i < len1; ++i) {
      for(int j = 1; j <= len2; ++j) {
        int parity = i & 1;
        dp[parity][j] = max(dp[!parity][j], dp[parity][j - 1]);
        if(s2[j - 1] == s1[i]) {
          dp[parity][j] = max(dp[parity][j], dp[!parity][j - 1] + 1);
        }
      }
    }
    return len1 + len2 - 2 * dp[!(len1 & 1)][len2];
  }
  bool isPalindrome(string &s) {
    int len = s.length();
    for(int i = 0; i * 2 < len; ++i) {
      if(s[i] != s[len - 1 - i]) return false;
    }
    return true;
  }
public:
  int minInsertions(string s) {
    if(isPalindrome(s)) return 0;
    int len = s.length();
    int answer = len - 1;
    string l;
    string r = s;
    dp.resize(2, vector<int>(len + 1));
    for(int i = 1; i < len; ++i) {
      char c = r.back();
      r.pop_back();
      if(len - 2 * min(i, len - i) >= answer) continue;
      answer = min(answer, minInsert(l, r));
      l.push_back(c);
      answer = min(answer, minInsert(l, r));
    }
    return answer;
  }
};

// abcdefg
// ab gfedc

finaly, I read other's post and realized...

auto speedup = []() {
  std::ios::sync_with_stdio(false);
  cin.tie(nullptr);
  cout.tie(nullptr);
  return nullptr;
}();
class Solution {
  int LCS(string &s1, string &s2) {
    int len1 = s1.length();
    int len2 = s2.length();
    // cout << "$$$$$$";
    vector<vector<int>> dp(2, vector<int>(len2 + 1));
    for(int i = 0; i < len1; ++i) {
      for(int j = 1; j <= len2; ++j) {
        int parity = i & 1;
        dp[parity][j] = max(dp[!parity][j], dp[parity][j - 1]);
        if(s2[j - 1] == s1[i]) {
          dp[parity][j] = max(dp[parity][j], dp[!parity][j - 1] + 1);
        }
      }
    }
    return dp[!(len1 & 1)][len2];
  }
  bool isPalindrome(string &s) {
    int len = s.length();
    for(int i = 0; i * 2 < len; ++i) {
      if(s[i] != s[len - 1 - i]) return false;
    }
    return true;
  }
public:
  int minInsertions(string s) {
    if(isPalindrome(s)) return 0;
    string r = s;
    reverse(r.begin(), r.end());
    return s.length() - LCS(s, r);
  }
}; 

April LeetCoding challenge 29

Description

Find First and Last Position of Element in Sorted Array

Given an array of integers nums sorted in ascending order, find the starting and ending position of a given target value.

If target is not found in the array, return [-1, -1].

Follow up: Could you write an algorithm with O(log n) runtime complexity?

Example 1:

Input: nums = [5,7,7,8,8,10], target = 8
Output: [3,4]

Example 2:

Input: nums = [5,7,7,8,8,10], target = 6
Output: [-1,-1]

Example 3:

Input: nums = [], target = 0
Output: [-1,-1]

Constraints:

  • 0 <= nums.length <= 105
  • -109 <= nums[i] <= 109
  • nums is a non-decreasing array.
  • -109 <= target <= 109

Solution

class Solution {
public:
  vector<int> searchRange(vector<int>& nums, int target) {
    int len = nums.size();
    if(!len) return{-1, -1};
    int begin = 0;
    int end = len - 1;
    while(begin < end) {
      int mid = (begin + end) >> 1;
      if(nums[mid] < target) {
        begin = mid + 1;
      } else {
        end = mid;
      }
    }
    if(nums[begin] != target) return {-1, -1};
    int left = begin;
    begin = 0;
    end = len - 1;
    while(begin < end) {
      int mid = (begin + end + 1) >> 1;
      if(nums[mid] > target) {
        end = mid - 1;
      } else {
        begin = mid;
      }
    }
    return {left, begin};
  }
};
class Solution {
public:
  vector<int> searchRange(vector<int>& nums, int target) {
    int len = nums.size();
    if(!len) return{-1, -1};
    auto left = lower_bound(nums.begin(), nums.end(), target);
    if((left == nums.end()) || (*left != target)) return {-1, -1};
    auto right = upper_bound(nums.begin(), nums.end(), target);
    --right;
    int l = left - nums.begin();
    int r = right - nums.begin();
    return {l, r};
  }
};