Problem Statement
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.
A valid IP:
- Has 4 parts (a.b.c.d)
- Each part is between 0 and 255
- No part can have leading zeros, except "0" itself
LeetCode
Constraints
1 <= s.length <= 20
s consists of digits only.Examples
Example 1:
Input: s = "25525511135"
Output: ["255.255.11.135","255.255.111.35"]Example 2:
Input: s = "0000"
Output: ["0.0.0.0"]Example 3:
Input: s = "101023"
Output: ["1.0.10.23","1.0.102.3","10.1.0.23","10.10.2.3","101.0.2.3"]Different Approaches
1️⃣ Backtracking
🎯 Idea:
- Try to insert dots in all valid positions to split into 4 parts
- At each step:
- Choose 1 to 3 digits for a segment
- Check if it's a valid segment
- Recursively proceed to next segment
Code:
class Solution {
public:
// Helper function to check if a segment of the IP is valid
bool valid(string part) {
// An empty string is not valid
if (part.empty()) return false;
// If the segment starts with '0' and is longer than 1 character, it's invalid (e.g., "01", "001")
if (part.size() > 1 && part[0] == '0') return false;
// Convert the string to an integer
int num = stoi(part);
// Check if the number is within the valid range for an IP segment (0 to 255)
return num >= 0 && num <= 255;
}
// Recursive function to try placing dots and building valid IP addresses
void solve(vector<string>& result, string& s, int index, int dots, string currStr) {
// Base case:
// If we've placed 4 dots and reached the end of the string, it's a valid IP address
if (dots == 4 && index == s.size()) {
// Remove the last extra '.' and store the result
result.push_back(currStr.substr(0, currStr.size() - 1));
return;
}
// If we placed more than 4 dots or went past the string, it's invalid
if (dots > 4) return;
// Try to place a dot after 1 to 3 digits
for (int cut = 1; cut <= 3; cut++) {
// If the cut goes beyond the string length, stop
if (index + cut > s.size()) break;
// Take a part of the string from current index with length = cut
string part = s.substr(index, cut);
// Check if this segment is valid
if (valid(part)) {
// Recurse with:
// - index moved forward by `cut` characters
// - one more dot placed
// - current segment added to the temporary result string (with a dot)
solve(result, s, index + cut, dots + 1, currStr + part + ".");
}
}
}
// Main function to start the process
vector<string> restoreIpAddresses(string s) {
vector<string> result;
// Start recursion from index 0, 0 dots placed, and empty current string
solve(result, s, 0, 0, "");
// Return all collected valid IP addresses
return result;
}
};
Complexity Analysis:
- Time Complexity:
O(1)- The max number of valid IPs is bounded.
- At most 3 choices (1-3 digits) for each of 4 segments =
O(3^4) = 0(81) - So, it's constant time, although we call it
O(1)in practice due to short input limits.
- Space Complexity:
O(1)- Recursion stack at most depth 4.
- Output list could hold up to 100 valid IPs in rare case →
O(k)forkanswers.
