Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added a new algorithm within strings module #890

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -356,6 +356,7 @@ If you want to uninstall algorithms, it is as simple as:
- [longest_palindromic_substring](algorithms/strings/longest_palindromic_substring.py)
- [knuth_morris_pratt](algorithms/strings/knuth_morris_pratt.py)
- [panagram](algorithms/strings/panagram.py)
- [swapcharacters](algorithms/strings/swap_str.py)
- [tree](algorithms/tree)
- [bst](algorithms/tree/bst)
- [array_to_bst](algorithms/tree/bst/array_to_bst.py)
Expand Down
71 changes: 71 additions & 0 deletions algorithms/strings/swap_str.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
"""
Given two strings s1 and s2, we are allowed to swap only one character from s1 with that of s2
such that after the swap, the total number of distinct characters in both s1 and s2 are the same.
If it is possible to perform such a swap, we should return True, else return False.

Example 1:
String 1: "cd", String 2: "e"
Expected Output: False
Explanation: On swapping the character c with e, we will end up with 2 distinct characters in string 1
and 1 character in string 2. Same goes with swapping character d with e.

Example 2:
String 1: "deff", String 2: "dde"
Expected Output: True
Explanation: We can swap character f in string 1 with character d in string 2. Hence, the new strings
will be dedf and fde. Both the string will contain three distinct characters, i.e. f, d and e.

Approach:
Create distinct prefix arrays for both string 1 and string 2. Then apply brute force to swap each of the
characters of string 1 with that of string 2 and notice if the number of distinct characters are the same.
If yes, then return True. Else, return False after all the swaps are complete.

If N is the size of string 1 and M is the size of string 2, then:

Time Complexity: O(N+M+26*26), where a complexity of N+M is required to create the prefix arrays. Also,
26*26 different swaps are required in the worst case scenario.

Space Complexity: O(26+26)=O(52) for creating the prefix arrays.
"""

# Function to create the Prefix Array.
def createPrefixArray(string):
array,count=[0]*26,0
for w in string:
array[ord(w)-ord('a')]+=1
if array[ord(w)-ord('a')]==1:
count+=1
return array,count

def checkSwapEquality(string1,string2):
prefixArray1,leftCount=createPrefixArray(string1) # Time Complexity of O(N)
prefixArray2,rightCount=createPrefixArray(string2) # Time Complexity of O(M)
for i in range(26): # Time Complexity of O(26*26)
if prefixArray1[i]: # Enter only if the character count is greater than 0
prefixArray1[i]-=1
if prefixArray1[i]==0:
leftCount-=1
prefixArray2[i]+=1
if prefixArray2[i]==1:
rightCount+=1
for j in range(26):
l,r=leftCount,rightCount
if prefixArray2[j]:
flag=True
if i==j and prefixArray2[j]==1:
flag=False
if flag:
if prefixArray1[j]==0:
l+=1
if prefixArray2[j]==1:
r-=1
if l==r:
return True
prefixArray1[i]+=1
prefixArray2[i]-=1
if prefixArray1[i]==1:
leftCount+=1
if prefixArray2[i]==0:
rightCount-=1
return False

21 changes: 21 additions & 0 deletions tests/test_swap_str.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
from algorithms.strings import (
swap_str,
)

import unittest

class Testswap_str(unittest.TestCase):
def test_swap_str1(self):
self.assertEqual(swap_str.checkSwapEquality('aabc','abcd'),True)

def test_swap_str2(self):
self.assertEqual(swap_str.checkSwapEquality('abcdef', 'fghijk'), True)

def test_swap_str3(self):
self.assertEqual(swap_str.checkSwapEquality('aab', 'c'), False)

def test_swap_str4(self):
self.assertEqual(swap_str.checkSwapEquality('mnopppq', 'xyzaa'), True)

if __name__ == '__main__':
unittest.main()