Skip to content
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
113 changes: 113 additions & 0 deletions ContiguousArray.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
//
// ContiguousArray.swift
// DSA-Practice
//
// Created by Paridhi Malviya on 1/3/26.
//

/*
Balanced array/ contiguous array - having equal no of 0s and 1s
[0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0...]
n, n-1, n-2, n-3, ....3,2,1, -> sum of all. aithmetic progression. n(n+1)/2 == n2 time complexity
//to check the balanced subarrays (having equal no of 0s and 1s) - n2 to form all subarrays. O(n) to check if it's subarray. So total time complexity - O(n3)

to check 0s and 1s - for each 0, reduce count by 1. For 1, increase the count by 1. If this counts become s0 at kast, it means it;s balanced subarrays.
When the running sum becomes equal, we have balanced subarrays
//check if a particular running sum happened before. How to check if a runnin gsum happened before or not ? -> Hash map
hashmap is a data structure - to search effectively in O(1)

Running sum / prefix sum -
[1, 2, 3, 4, 5, 6, 7, 8, 9,]
1, 3, 6, 10, 15, 16, 23, 31, 40

Time complexity -> O(n)
Space complexity -> O(n)

Edge case - if the balanced suabarray is startng from index 0, we are not able to catch
so, make a dummy entry for catching (-1, 0) (the running sum is 0 at -1 index) to catch the subarray starting from 0th index. Because
Index of the balanced subarray is starting from (index+1). index is the array index where the sum is equal to the current index's sum.
We are eliminating nested array because if we have value of x and y, then we can calculate z if x-y = z. z happens to be the nested iteration.
*/

import Foundation

class ContiguousArray {

//Running sum problem
//with equal no of 0s and 1s
func findMaxBalancedArrayLength() -> Int {
//[0,1] = output 1. balanced array
//[0,1,0] -> output 2, [0,1] & [1,0]
let nums = [0, 1, 1, 1, 1, 1, 0, 0, 0]

var maxLength = 0
//first create a counter variable. Incremenet it in presence of 1, decrement it in presence of 0
var sumMap: [Int: Int] = [0: -1] //sum is 0 at -1 index [sum: index]
var rSum = 0 // at
for i in 0..<nums.count {
if (nums[i] == 0) {
//decremtn counter by 1
rSum -= 1
} else {
//increment counter by 1
rSum += 1
}

if (sumMap[rSum] != nil) {
//it means this counter already exists in the map, so take that out and the current one, find the difference. Thta would be the balanced subarray.
let existinIndexWithTheSameSum = sumMap[rSum]!
if (i - existinIndexWithTheSameSum > maxLength) {
maxLength = i - existinIndexWithTheSameSum
}
// maxLength = max(maxLength, i - sumMap[rSum]!)
} else {
sumMap[rSum] = i //for a particular sum, save the index
}
}

//to find the longest subarray with equal no of 0s and 1s.
return maxLength
}

func findLengthOfLongestBalancedSubarray() -> Int {
let nums = [0, 1, 1, 1, 1, 1, 0, 0, 0]
if nums.isEmpty { return 0 }

var map: [Int: Int] = [Int: Int]()
var maxLen = 0
var rSum = 0 //runningSum
map[0] = -1 // 0 sum happend at -1 index
// var start = 0
// var end = 0
for i in 0..<nums.count {
if (nums[i] == 0) {
rSum -= 1
} else {
rSum += 1
}
//check if the sum is contained in the map
if (map[rSum] != nil) {
//so length of current subarray is
var curr = i - map[rSum]!
// if (maxLen < curr) {
// maxLen = curr
// start = map[rSum]
// end = i
// }
maxLen = max(maxLen, curr)
} else {
map[rSum] = i
}
}
return maxLen
}

init() {
let maxLength = findLengthOfLongestBalancedSubarray()
print("maxLength *** \(maxLength)")
let len = findMaxBalancedArrayLength()
print("length *** \(len)")

}
}

48 changes: 48 additions & 0 deletions LongestPalindrome.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
//
// LongestPalindrome.swift
// DSA-Practice
//
// Created by Paridhi Malviya on 12/30/25.
//

class LongestPalindrome {

var set: Set<Character> = Set<Character>()
var count = 0

/*
"abccccdd" - make longest palindrome.
1. Approach 1 - Use hashmap, keep on increamenting the frequncy of characters in the map for a unique character. Use even ones and add length 2. T last choose any of a 1 frequency character and make the palindrome.
Space complexity - O(1)
time complexity = O(n)

2. Approach 2: Use Set. Add 1 characetr in set. If next character is the same then remove the character from set and add 2 in length. Atlast, you we will have unique character with legth 1. Take any of character and form the palindrome.
time complexity - O(n) //iterating over the string
space complexity O (1) perfectly // We will not be cotainging more tha 52 characetrs in the set, So it will be constant.

3. Approach 2
*/

init() {
let length = findLongestPalindrome(str: "abccccdd")
print("length \(length)")
}

func findLongestPalindrome(str: String) -> Int {
//Approach 2 - Set solutioh
var set = Set<Character>()
var lengthOfPalindrome = 0
for char in str {
if (set.contains(char)) {
lengthOfPalindrome += 2
set.remove(char)
} else {
set.insert(char)
}
}
if (!set.isEmpty) {
return lengthOfPalindrome + 1
}
return lengthOfPalindrome
}
}
63 changes: 63 additions & 0 deletions SubArraySumK.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
//
// SubArraySumK.swift
// DSA-Practice
//
// Created by Paridhi Malviya on 1/4/26.
//

class SubarraySumK {

//Time compelxity - O(n)
//Space complexity - O(n
/*
find relationship between x, y and z. If we know any of two variables, we can eleiminate nested arrays
Initially see the brute forcea approach which contains nested iterations. In this case, explore running sum pattern (either running sum happened or compliment has happened)
For optimizing search, maintain hashing based data structures.
if we want have frequency or length then use map
If we want to see if that running sum happened or not, use Set

***** Keep in mind whether we are missing subarray which are starting from 0th index or not.

Nested iterations can be eliminated by
1. Prefix sum pattern
2. Sliding window
3. Two pointers
4. Sorted array binary search
5. hashing
6. In some case, DP
7. In some cases - monotonic increasing sum

*/
func subArrayCount() -> Int{
let input = [3, 4, 7, 2, -3, 1, 4, 2, 0, 1]
let k = 7

//create a map to keep track of the sum and how many times it occurred
//Have dummy value [0: 1] which says that sum 0 happened once. This is to catch an edge case where the subarray is starting from index 0.
var map: [Int: Int] = [0: 1]
var rSum: Int = 0
var countOfSubArray = 0
for index in 0..<input.count {
//it means the value is present in the map
rSum = rSum + input[index]
let compliment = rSum - k

if (map[compliment] != nil) {
//check if the compliment exist in the map, it means
countOfSubArray += map[compliment]!
}

if (map[rSum] != nil) {
map[rSum]! += 1
} else {
map[rSum] = 1 //this rSum has happened once
}
}
return countOfSubArray
}

init() {
let count = subArrayCount()
print("count \(count)")
}
}