Journey of LeetCode|DAY 24
Preface
This is a new day to continue my backtracking algorithm journey.
Learn something new and keep reviewing what I learnt before.
1. Restore IP Addresses
LeetCode Link: 93. Restore IP Addresses
A valid IP address consists of exactly four integers separated by single dots. Each integer is between 0 and 255 (inclusive) and cannot have leading zeros.
For example, “0.1.2.201” and “192.168.1.1” are valid IP addresses, but “0.011.255.245”, “192.168.1.312” and “192.168@1.1” are invalid IP addresses.
Given a string s containing only digits, return all possible valid IP addresses that can be formed by inserting dots into s. You are not allowed to reorder or remove any digits in s. You may return the valid IP addresses in any order.
Analysis and Solution
BackTrack
LeetCode C++ as followings BackTrack
class Solution {
private:
vector<string> result;// store results
// startIndex: start position of search,pointNum: Number of commas to add
void backtracking(string& s, int startIndex, int pointNum) {
if (pointNum == 3) { // the separation ends When the number of commas is 3
// judge whether the fourth substring is legal, and put it in the result if it is legal
if (isValid(s, startIndex, s.size() - 1)) {
result.push_back(s);
}
return;
}
for (int i = startIndex; i < s.size(); i++) {
if (isValid(s, startIndex, i)) { // judge if substring of [startIndex,i] is legal
s.insert(s.begin() + i + 1 , '.'); // insert comma after i
pointNum++;
backtracking(s, i + 2, pointNum); // the start position of next substring is i+2 after inserting the comma
pointNum--; // backtrack
s.erase(s.begin() + i + 1); // delete comma in the precess of backtrack
} else break; // end loop if it is not legal
}
}
// judge whether the number composed of the string s in the left-closed and right-closed interval [start, end] is legal
bool isValid(const string& s, int start, int end) {
if (start > end) {
return false;
}
if (s[start] == '0' && start != end) { // Numbers starting with 0 are illegal
return false;
}
int num = 0;
for (int i = start; i <= end; i++) {
if (s[i] > '9' || s[i] < '0') { // Illegal non-numeric character encountered
return false;
}
num = num * 10 + (s[i] - '0');
if (num > 255) { // number > 255 is illegal
return false;
}
}
return true;
}
public:
vector<string> restoreIpAddresses(string s) {
result.clear();
if (s.size() < 4 || s.size() > 12) return result; // just like removing the branch
backtracking(s, 0, 0);
return result;
}
};
2. Subsets
LeetCode Link: 78. Subsets
Given an integer array nums of unique elements, return all possible
subsets (the power set).
The solution set must not contain duplicate subsets. Return the solution in any order.
Analysis and Solution
BackTrack
LeetCode C++ as followings BackTrack
class Solution {
private:
vector<vector<int>> result;
vector<int> path;
void backtracking(vector<int>& nums, int startIndex) {
result.push_back(path); // collect the subset,put above the terminate condition in case miss itself
if (startIndex >= nums.size()) { // here is terminate condition; delete it is ok; it isnot necessary of the process
return;
}
for (int i = startIndex; i < nums.size(); i++) {
path.push_back(nums[i]);//subset collects the elements
backtracking(nums, i + 1);//start from i+1; Elements are not repeated
path.pop_back();//backtrack
}
}
public:
vector<vector<int>> subsets(vector<int>& nums) {
result.clear();
path.clear();
backtracking(nums, 0);
return result;
}
};
3. Subsets II
LeetCode Link: 90. Subsets II
Given an integer array nums that may contain duplicates, return all possible
subsets (the power set).
The solution set must not contain duplicate subsets. Return the solution in any order.
Analysis and Solution
BackTrack
LeetCode C++ as followings BackTrack
class Solution {
private:
vector<vector<int>> result;
vector<int> path;
void backtracking(vector<int>& nums, int startIndex, vector<bool>& used) {// 'used' is to judge if it is was used
result.push_back(path);
for (int i = startIndex; i < nums.size(); i++) {
// used[i - 1] == true,indicates candidates[i - 1] on the same branch of tree was uesd
// used[i - 1] == false,indicates candidates[i - 1] on the same layer of the tree was used
// skip the elements that was used on the same layer of the tree
if (i > 0 && nums[i] == nums[i - 1] && used[i - 1] == false) {
continue;
}
path.push_back(nums[i]);
used[i] = true;
backtracking(nums, i + 1, used);// backtrack
used[i] = false;
path.pop_back();//pop the duplicate value
}
}
public:
vector<vector<int>> subsetsWithDup(vector<int>& nums) {
result.clear();
path.clear();
vector<bool> used(nums.size(), false);
sort(nums.begin(), nums.end()); // Deduplication needs to be sorted
backtracking(nums, 0, used);
return result;
}
};