TheAlgorithms-Ruby/data_structures/arrays/strings/palindrome.rb

128 lines
3 KiB
Ruby
Raw Normal View History

2021-04-01 18:31:12 +02:00
# Challenge name: Valid Palindrome
#
# Given a string s, determine if it is a palindrome,
# considering only alphanumeric characters and ignoring cases.
#
# Example 1:
# Input: s = "A man, a plan, a canal: Panama"
# Output: true
# Explanation: "amanaplanacanalpanama" is a palindrome.
#
# Example 2:
# Input: s = "race a car"
# Output: false
# Explanation: "raceacar" is not a palindrome.
#
# Constraints:
# 1 <= s.length <= 2 * 105
# s consists only of printable ASCII characters.
# @param {String} s
# @return {Boolean}
#
2021-04-05 22:57:41 +02:00
# Approach 1: Using Ruby method .reverse
2021-04-01 18:31:12 +02:00
#
2021-04-05 22:57:41 +02:00
# Time Complexity: O(n)
2021-04-01 18:31:12 +02:00
#
def is_palindrome(s)
2021-04-05 22:57:41 +02:00
letters_only = s.downcase.gsub(/[^0-9a-z]/i, '')
letters_only.reverse == letters_only
2021-04-01 18:31:12 +02:00
end
s = 'A man, a plan, a canal: Panama'
puts is_palindrome(s)
# Output: true
# Explanation: "amanaplanacanalpanama" is a palindrome.
s = 'race a car'
puts is_palindrome(s)
# Output: false
# Explanation: "raceacar" is not a palindrome.
2021-04-05 23:08:23 +02:00
s = 'ab_a'
puts is_palindrome(s)
# Output: true
# Explanation: "aba" is a palindrome.
#
# Approach 2: Reversed array
#
# Complexity Analysis:
#
# Time Complexity: O(n), in length n of the string.
#
# We need to iterate through the string: When we filter out non-alphanumeric characters and convert the remaining
2021-09-03 22:24:58 +02:00
# characters to lower-case. When we reverse the string. When we compare the original and the reversed strings.
# Each iteration runs linearly in time (since each character operation completes in constant time).
# Thus, the effective run-time complexity is linear.
#
# Space Complexity: O(n), in length n of the string. We need O(n) additional
# space to store the filtered string and the reversed string.
2021-04-05 23:08:23 +02:00
#
def is_palindrome(s)
letters_only_array = s.downcase.gsub(/[^0-9a-z]/i, '').split('')
reversed_array = []
letters_only_array.each do |letter|
reversed_array.unshift(letter)
end
letters_only_array == reversed_array
end
s = 'A man, a plan, a canal: Panama'
puts is_palindrome(s)
# Output: true
# Explanation: "amanaplanacanalpanama" is a palindrome.
s = 'race a car'
puts is_palindrome(s)
# Output: false
# Explanation: "raceacar" is not a palindrome.
2021-04-05 23:31:57 +02:00
s = 'ab_a'
puts is_palindrome(s)
# Output: true
# Explanation: "aba" is a palindrome.
#
# Approach 2: Two Pointers
#
#
# Complexity Analysis:
#
# Time Complexity: O(n), in length n of the string. We traverse over each
# character at most once until the two pointers meet in the middle, or when
# we break and return early.
# Space Complexity: O(1). No extra space required, at all.
2021-04-05 23:31:57 +02:00
#
def is_palindrome(s)
letters_only = s.downcase.gsub(/[^0-9a-z]/i, '')
p1 = 0
p2 = letters_only.length - 1
while p1 < p2
if letters_only[p1] == letters_only[p2]
p1 += 1
p2 -= 1
else
return false
end
end
true
end
s = 'A man, a plan, a canal: Panama'
puts is_palindrome(s)
# Output: true
# Explanation: "amanaplanacanalpanama" is a palindrome.
s = 'race a car'
puts is_palindrome(s)
# Output: false
# Explanation: "raceacar" is not a palindrome.
2021-04-01 18:31:12 +02:00
s = 'ab_a'
puts is_palindrome(s)
# Output: true
# Explanation: "aba" is a palindrome.