Skip to content

Commit 92f5234

Browse files
committed
multiple problems
1 parent 34ed2f4 commit 92f5234

7 files changed

+481
-0
lines changed
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
2+
class FileSystem {
3+
4+
var trie = Trie()
5+
init() {
6+
7+
}
8+
9+
func createPath(_ path: String, _ value: Int) -> Bool {
10+
return trie.insert(path, value)
11+
}
12+
13+
func get(_ path: String) -> Int {
14+
return trie.contains(path)
15+
}
16+
}
17+
18+
class TrieNode {
19+
var name: String
20+
var children: [String:TrieNode]
21+
var value: Int
22+
23+
init(_ name: String, _ value: Int = -1, children: [String:TrieNode] = [:]) {
24+
self.name = name
25+
self.children = children
26+
self.value = value
27+
}
28+
}
29+
30+
class Trie {
31+
var root: TrieNode
32+
33+
init () {
34+
root = TrieNode("/")
35+
}
36+
37+
func insert(_ path: String, _ value: Int) -> Bool {
38+
let pathComponents = path.split(separator: "/").map { String($0) }
39+
guard pathComponents.count > 0 else {
40+
return false
41+
}
42+
43+
var currentNode = root
44+
for (_, item) in pathComponents.enumerated() {
45+
if currentNode.children[item] == nil {
46+
if item == pathComponents.last {
47+
let newNode = TrieNode(item)
48+
currentNode.children[item] = newNode
49+
} else {
50+
return false
51+
}
52+
}
53+
currentNode = currentNode.children[item]!
54+
}
55+
56+
if currentNode.value != -1 {
57+
return false
58+
} else {
59+
currentNode.value = value
60+
return true
61+
}
62+
}
63+
64+
func contains(_ path: String) -> Int {
65+
let pathComponents = path.split(separator: "/").map { String($0) }
66+
guard pathComponents.count > 0 else {
67+
return -1
68+
}
69+
70+
var currentNode = root
71+
for (_, item) in pathComponents.enumerated() {
72+
if let nextNode = currentNode.children[item] {
73+
currentNode = nextNode
74+
} else {
75+
return -1
76+
}
77+
}
78+
return currentNode.value
79+
}
80+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
// Simple DFS without memoization. TLE
2+
class Solution {
3+
func shortestPath(_ grid: [[Int]], _ k: Int) -> Int {
4+
let m = grid.count, n = grid[0].count
5+
var minSteps = Int.max, visitedGrid = Array(repeating: Array(repeating: -1, count: n), count: m)
6+
shortestPathDFSHelper(grid, k, k, 0, 0, 0, &minSteps, &visitedGrid)
7+
return minSteps == Int.max ? -1 : minSteps
8+
}
9+
10+
func shortestPathDFSHelper(
11+
_ grid: [[Int]],
12+
_ k: Int,
13+
_ remainingK: Int,
14+
_ startRowIdx: Int,
15+
_ startColIdx: Int,
16+
_ currentSteps: Int,
17+
_ minSteps: inout Int,
18+
_ visitedGrid: inout [[Int]]
19+
) {
20+
let m = grid.count, n = grid[0].count
21+
if remainingK < 0 {
22+
return
23+
}
24+
if startRowIdx == m - 1 && startColIdx == n - 1 {
25+
minSteps = min(minSteps, currentSteps)
26+
return
27+
}
28+
29+
for (r, c) in [(0, -1), (-1, 0), (0, 1), (1, 0)] {
30+
let newR = startRowIdx + r, newC = startColIdx + c
31+
if newR < 0 || newR >= m || newC < 0 || newC >= n || visitedGrid[newR][newC] != -1 {
32+
continue
33+
}
34+
let cellVal = grid[newR][newC]
35+
visitedGrid[newR][newC] = 0 // marking this cell as visited
36+
if cellVal == 0 {
37+
shortestPathDFSHelper(grid, k, remainingK, newR, newC, currentSteps + 1, &minSteps, &visitedGrid)
38+
} else {
39+
shortestPathDFSHelper(grid, k, remainingK - 1, newR, newC, currentSteps + 1, &minSteps, &visitedGrid)
40+
}
41+
visitedGrid[newR][newC] = -1 // backtracking
42+
}
43+
}
44+
}
45+
46+
47+
// BFS with memoization. Accepted
48+
class Solution {
49+
func shortestPath(_ grid: [[Int]], _ k: Int) -> Int {
50+
let m = grid.count, n = grid[0].count
51+
var minSteps = Int.max, visitedGrid = Array(repeating: Array(repeating: Array(repeating: -1,
52+
count: k + 1),
53+
count: n),
54+
count: m)
55+
var queue = [(Int, Int, Int, Int)]() // (row, col, currentSteps, remainingRemoval)
56+
queue.append((0, 0, 0, k))
57+
while !queue.isEmpty {
58+
let (row, col, currentSteps, remainingRemoval) = queue.removeFirst()
59+
visitedGrid[row][col][remainingRemoval] = 0 // marking it as visited
60+
if row == m - 1 && col == n - 1 && remainingRemoval >= 0 {
61+
minSteps = min(minSteps, currentSteps)
62+
}
63+
64+
for (r, c) in [(0, -1), (-1, 0), (0, 1), (1, 0)] {
65+
let newR = row + r, newC = col + c
66+
if newR < 0 || newR >= m || newC < 0 || newC >= n {
67+
continue
68+
}
69+
70+
let cellVal = grid[newR][newC]
71+
let newRemainingRemoval = cellVal == 0 ? remainingRemoval : remainingRemoval - 1
72+
if newRemainingRemoval < 0 || visitedGrid[newR][newC][newRemainingRemoval] != -1 {
73+
continue
74+
}
75+
76+
visitedGrid[newR][newC][newRemainingRemoval] = 0 // marking this cell as visited
77+
queue.append((newR, newC, currentSteps + 1, newRemainingRemoval))
78+
}
79+
}
80+
return minSteps == Int.max ? -1 : minSteps
81+
}
82+
}
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
// Linear search. Time: O(n^2). TLE for big input
2+
class Solution {
3+
func getFolderNames(_ names: [String]) -> [String] {
4+
var counter = [String:Int]()
5+
var result = [String]()
6+
for name in names {
7+
if counter[name] == nil {
8+
counter[name, default: 0] += 1
9+
result.append(name)
10+
continue
11+
}
12+
var k = counter[name]!, newName = "\(name)(\(k))"
13+
while counter[newName] != nil {
14+
k += 1
15+
newName = "\(name)(\(k))"
16+
}
17+
counter[newName, default: 0] += 1
18+
result.append(newName)
19+
}
20+
return result
21+
}
22+
}
23+
24+
// Linear search. Time: O(n^2). Similar to mi above one but it's accepted. No idea why? https://tinyurl.com/yy9kwrbm
25+
class Solution {
26+
func getFolderNames(_ names: [String]) -> [String] {
27+
var dict : [String:Int] = [:]
28+
var res : [String] = []
29+
for n in names{
30+
if dict[n] == nil{
31+
dict[n] = 0
32+
res.append(n)
33+
}
34+
else{
35+
if dict[n] != nil{
36+
var i = dict[n]! + 1
37+
var val = n + String("(\(i))")
38+
while(dict[val] != nil) {
39+
i += 1
40+
val = n + String("(\(i))")
41+
}
42+
dict[n] = i
43+
dict[val] = 0
44+
res.append(val)
45+
}
46+
}
47+
}
48+
return res
49+
}
50+
}
51+
52+
// Binary search. Time: O(n). Wrong answer for some cases
53+
class Solution {
54+
func getFolderNames(_ names: [String]) -> [String] {
55+
var counter = [String:Int]()
56+
var result = [String]()
57+
for name in names {
58+
if counter[name] == nil {
59+
counter[name, default: 0] += 1
60+
result.append(name)
61+
continue
62+
}
63+
var startK = counter[name]!, endK = names.count
64+
while startK < endK {
65+
let midK = startK + ((endK - startK) / 2)
66+
let newName = "\(name)(\(midK))"
67+
if counter[newName] == nil {
68+
endK = midK
69+
} else {
70+
startK = midK + 1
71+
}
72+
}
73+
let newName = "\(name)(\(startK))"
74+
counter[newName, default: 0] += 1
75+
result.append(newName)
76+
}
77+
return result
78+
}
79+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import Foundation
2+
3+
// Min Heap
4+
class Solution {
5+
func furthestBuilding(_ heights: [Int], _ bricks: Int, _ ladders: Int) -> Int {
6+
var currentLadderAllocationMinHeap = Heap<Int>(sort: <), currentBrickAllocation = 0 //SOURCE: https://github.com/raywenderlich/swift-algorithm-club/blob/master/Heap/Heap.swift
7+
for index in 0..<heights.count - 1 {
8+
let currentHeight = heights[index], nextHeight = heights[index + 1], climb = nextHeight - currentHeight
9+
if climb <= 0 {
10+
continue
11+
}
12+
currentLadderAllocationMinHeap.insert(climb)
13+
if currentLadderAllocationMinHeap.count <= ladders {
14+
continue
15+
}
16+
let neededBricks = currentLadderAllocationMinHeap.remove()!
17+
currentBrickAllocation += neededBricks
18+
if currentBrickAllocation > bricks {
19+
return index
20+
}
21+
}
22+
return heights.count - 1
23+
}
24+
}
25+
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
2+
// Getting TLE for some test cases due to infinit loop. No idea what's going wrong here, though spent a lot of time to figure it out
3+
import Foundation
4+
class Solution {
5+
func minSpeedOnTime(_ dist: [Int], _ hour: Double) -> Int {
6+
var minSpeed = 1, maxSpeed = dist.max()!
7+
while minSpeed < maxSpeed {
8+
let midSpeed = ((minSpeed + (maxSpeed - minSpeed)) / 2) + 1
9+
let totalTime = getTotalTimeFor(midSpeed, dist, hour)
10+
if totalTime > hour {
11+
minSpeed = midSpeed + 1
12+
} else {
13+
maxSpeed = midSpeed
14+
}
15+
}
16+
return getTotalTimeFor(minSpeed, dist, hour) <= hour ? minSpeed : -1
17+
}
18+
19+
func getTotalTimeFor(_ speed: Int, _ dist: [Int], _ hour: Double) -> Double {
20+
var totalTime = 0.0
21+
for distance in dist {
22+
let currentTime = Double(Double(distance)/Double(speed))
23+
if distance == dist.last! {
24+
totalTime += currentTime
25+
} else {
26+
totalTime += currentTime.rounded(.up)
27+
}
28+
}
29+
return totalTime
30+
}
31+
}

0 commit comments

Comments
 (0)