Two pointer approach is useful in solving Array & String problems.
Palindrome
Problem:
Write a function, is_palindrome, that takes in a string and returns a boolean indicating whether or not the string is the same forwards and backwards.
Solution:
i initiated at the start of array
j initiated at the endof array
Will have an while loop & inside that, will start comparing the character at i & j for each iteration.
If the values do not match at any point of time, return False. Suppose you could able to successfully come out of the loop, it means that the given string is an palindrome & hence will return True.

def is_palindrome(s):
i = 0
j = len(s) - 1
while i < j:
if s[i] != s[j]:
return False
i += 1
j -= 1
return True
Uncompress
Problem:
Write a function, uncompress, that takes in a string as an argument.
The input string will be formatted into multiple groups according to the following pattern:
uncompress("2c3a1t") # -> 'ccaaat'
The function should return an uncompressed version of the string where each ‘char’ of a group is repeated ‘number’ times consecutively. You may assume that the input string is well-formed according to the previously mentioned pattern.
Solution:
i = 0
j = 0
Keep incrementing j until you find an character. It means, you found the character which needs to be repeated.

def uncompress(s):
numbers = "0123456789"
result = []
i = 0
j = 0
while j < len(s):
if s[j] in numbers:
j += 1
else:
num = int(s[i:j])
result.append(s[j] * num)
j += 1
i = j
return "".join(result)
Compress
Problem:
Write a function, compress, that takes in a string as an argument. The function should return a compressed version of the string where consecutive occurrences of the same characters are compressed into the number of occurrences followed by the character. Single character occurrences should not be changed.
'aaa' compresses to '3a'
'cc' compresses to '2c'
't' should remain as 't'
You can assume that the input only contains alphabetic characters.
Solution:
i = 0
j = 0
Keep incrementing j until you find an character. It means, you found the character which needs to be repeated.

def compress(s):
# Explanation for s += '!' line of code.
# See how you are doing your work inside the while loop.
# You are staring at both i and j at index 0.
# Then incrementing j until you find an new character
# which is different than i.
# But, there is a catch. When you come across the last streak,
# you can't do that, because, that's the end streak &
# there is no chartacter at the end which is different
# than the streak. That's why you need to add ! at the end.
s += "!"
i = 0
j = 0
result = []
while j != len(s):
if s[i] == s[j]:
j += 1
else:
num = j - i
if num == 1:
result.append(s[i])
else:
temp_result = s[i] * num
result.append(str(num))
result.append(s[i])
i = j
return "".join(result)
Five sort
Problem:
Write a function, five_sort, that takes in a list of numbers as an argument. The function should rearrange elements of the list such that all 5s appear at the end. Your function should perform this operation in-place by mutating the original list. The function should return the list.
Elements that are not 5 can appear in any order in the output, as long as all 5s are at the end of the list.
Important: Your function needs to mutate the original list in-place and should not return a new list. It will fail the test cases if you do not modify the original input list.
Solution:
Will initiate two pointers as shown in the figure. One pointer at the start of array & another at the end of array.

And then the logic goes like this:
Increament the i pointer until you find non 5.
Decrement j pointer until you find 5.
Then swap

When i & j are met, then stop the algorithm

def five_sort(nums):
i = 0
j = len(nums) - 1
while i < j:
if nums[i] == 5 and nums[j] != 5:
nums[i], nums[j] = nums[j], nums[i]
else:
if nums[i] != 5:
i += 1
if nums[j] == 5:
j -= 1
return nums
Subsequence
Problem:
Write a function, is_subsequence, that takes in string_1 and string_2.
The function should return a boolean indicating whether or not string_1 is a subsequence of string_2.
A subsequence is a string that can be formed by deleting 0 or more characters from another string.
Solution:
While you are doing this, if i == len(str_1), means you are successfully found all the characters that are present in str_1 in str_2 in sequential order.
i & j will be initiated at the starting of the strings.
Until i find str_1[i] == str_2[j], keep incrementing j → Once the match is found,increment both i & j.

def is_subsequence(string_1, string_2):
i = 0
j = 0
while i != len(string_1) and j != len(string_2):
if string_2[j] != string_1[i]:
j += 1
else:
i += 1
j += 1
return i == len(string_1)
