class Solution:
def isStrobogrammatic(self, num: str) -> bool:
mapping = {'0': '0', '1': '1', '6': '9', '8': '8', '9': '6'}
left, right = 0, len(num) - 1
while left <= right:
if num[left] not in mapping or num[right] not in mapping:
return False
if mapping[num[left]] != num[right]:
return False
left += 1
right -= 1
return True
class Solution {
public:
bool isStrobogrammatic(string num) {
unordered_map<char, char> mapping = {
{'0', '0'}, {'1', '1'}, {'6', '9'}, {'8', '8'}, {'9', '6'}
};
int left = 0, right = num.size() - 1;
while (left <= right) {
if (mapping.find(num[left]) == mapping.end() ||
mapping.find(num[right]) == mapping.end())
return false;
if (mapping[num[left]] != num[right])
return false;
left++;
right--;
}
return true;
}
};
class Solution {
public boolean isStrobogrammatic(String num) {
Map<Character, Character> map = new HashMap<>();
map.put('0', '0');
map.put('1', '1');
map.put('6', '9');
map.put('8', '8');
map.put('9', '6');
int left = 0, right = num.length() - 1;
while (left <= right) {
char l = num.charAt(left);
char r = num.charAt(right);
if (!map.containsKey(l) || !map.containsKey(r)) return false;
if (map.get(l) != r) return false;
left++;
right--;
}
return true;
}
}
/**
* @param {string} num
* @return {boolean}
*/
var isStrobogrammatic = function(num) {
const map = {'0':'0', '1':'1', '6':'9', '8':'8', '9':'6'};
let left = 0, right = num.length - 1;
while (left <= right) {
if (!(num[left] in map) || !(num[right] in map)) return false;
if (map[num[left]] !== num[right]) return false;
left++;
right--;
}
return true;
};
You are given a string num
representing a number. A strobogrammatic number is a number that looks the same when rotated 180 degrees (turned upside down). Return true
if num
is strobogrammatic, and false
otherwise.
0 <-> 0
, 1 <-> 1
, 6 <-> 9
, 8 <-> 8
, 9 <-> 6
.true
only if the whole number is strobogrammatic.At first glance, you might think to just reverse the string and check if it is the same as the original. However, strobogrammatic numbers are not palindromes. Instead, each digit must be replaced with its strobogrammatic counterpart and the string reversed.
The naive approach is to rotate the entire number, one digit at a time, and see if the result matches the original number. But we can optimize this by comparing matching pairs from the outside in, using two pointers. If any pair does not match the strobogrammatic mapping, we can return false early.
This approach minimizes unnecessary work and avoids extra space for building a new string.
{ '0':'0', '1':'1', '6':'9', '8':'8', '9':'6' }
.
left
at the start of the string and right
at the end.
num[left]
and num[right]
are both valid strobogrammatic digits. If not, return false.
mapping[num[left]] == num[right]
. If not, return false.
left
and decrement right
until they cross.
This approach is efficient because it only checks each digit once and stops as soon as a mismatch is found.
Let's walk through the example num = "619"
:
left = 0
('6'
), right = 2
('9'
). The mapping for '6' is '9', which matches num[2]
.
left = 1
('1'
), right = 1
('1'
). The mapping for '1' is '1', which matches num[1]
.
left = 2
, right = 0
. Loop ends. All pairs matched.
The function returns true
because "619" is strobogrammatic.
If we try num = "962"
:
left = 0
('9'
), right = 2
('2'
). '2' is not in the mapping, so we immediately return false
.
The optimized approach is preferred because it avoids building new strings and uses constant extra space.
To determine if a number is strobogrammatic, we check if each digit and its corresponding digit from the other end form a valid strobogrammatic pair. By using a two-pointer technique and a simple mapping, we efficiently solve the problem in linear time and constant space. The elegance of the solution lies in its directness and early exit on failure, making it both simple and optimal.