Swift Linked List Remove Duplicates - swift

I have written below program to remove duplicates from linked list,
Below is the code which contains Node Class and method to remove duplicates by traversing the linked list.
In method removeDuplicates, However it fails when i am performing while ( cur != nil ) check , when changed to cur.link != nil will work but the output is not correct.
import UIKit
class LinkedList {
class Node {
var data:Int
var link: Node?
init(data: Int = 0 ){
self.data = data
self.link = nil
}
}
func disp(n: Node?) -> String{
var text = String()
var node = n
while node != nil{
text += "\(node!.data)"
node = node?.link
if node != nil {
text += "--->"
}
}
return text
}
func removeDuplicatesNode( head : Node?) -> Node?{
var cur = head
var prev:Node? = nil
let s = NSMutableSet()
while ( cur != nil ) {
let val:Int = cur!.data
if( s.contains(val)){
prev?.link = cur?.link!
}else{
s.add(val)
prev = cur
}
print(cur)
cur = cur?.link
}
return head!
}
}
var list = LinkedList()
var removeDuplicates = LinkedList.Node(data: 1)
removeDuplicates.link = LinkedList.Node(data: 2)
removeDuplicates.link?.link = LinkedList.Node(data: 3)
removeDuplicates.link?.link?.link = LinkedList.Node(data: 3)
print("Remove Duplicates " + list.disp(n: (list.removeDuplicatesNode(head: removeDuplicates))))

Please review the updated removeDuplicateNode() function. I updated code with the nil condition.
func removeDuplicatesNode( head : Node?) -> Node?{
var cur = head
var prev:Node? = nil
let s = NSMutableSet()
while ( cur != nil ) {
let val:Int = cur!.data
if( s.contains(val)){
if cur?.link != nil { // Check for last Node
prev?.link = cur?.link!
}else{
prev?.link = nil // If last node then assign nil value to the prev node's link
}
}else{
s.add(val)
prev = cur
}
print(cur!)
cur = cur?.link
}
return head!
}
Thank You

Related

How do you assign and unwrap an optional array object in Swift?

I'm trying to invert a binary tree in Swift using the iterative approach. Essentially I just keep looping through each node, and putting it into a stack array. This array should be an array of optional nodes. Here is my code:
func invertTree(_ root: TreeNode?) -> TreeNode? {
if root != nil {
stack.append(root)
} else {
return root
}
var stack = [TreeNode?]()
while stack.count > 0 {
if stack.last == nil {
stack.removeLast()
} else {
var tempLeft : TreeNode? = stack.last!.left
stack.last!.left = stack.last!.right
stack.last!.right = tempLeft
if stack.last!.left != nil {
stack.append(stack.last!.left)
}
if stack.last.right != nil {
stack.append(stack.last!.right)
}
}
}
return root
}
I'm getting all sorts of optional errors. In particular, when I set:
var tempLeft : TreeNode? = stack.last!.left
I'm not sure why it says "value of optional type TreeNode? must be unwrapped to refer to member 'left' of unwrapped base type 'TreeNode' in solution.swift"
I don't understand why it's telling me to unwrap the optional, when I'm already force unwrapping it. I don't want to unwrap the .left node since I want to include nils in my stack for the iteration to work.
Any help would be greatly appreciated.
stack.last is a doubly optional TreeNode: TreeNode??.
You could use optional chaining like so:
if stack.last == nil {
stack.removeLast()
} else {
stack.last
var tempLeft : TreeNode? = stack.last!?.left
stack.last!?.left = stack.last!?.right
stack.last!?.right = tempLeft
if stack.last!?.left != nil {
stack.append(stack.last!?.left)
}
if stack.last??.right != nil {
stack.append(stack.last!?.right)
}
}
Or avoid the drama and use pattern matching:
if case let node?? = stack.last {
let tempLeft = node.left
node.left = node.right
node.right = tempLeft
...
Other than that, it seems that there are other areas of your code that you need to tend to. For example, using stack before its declaration.
Alternative implementation
Here is a solution that uses a stack:
class Solution {
func invertTree(_ root: TreeNode?) -> TreeNode? {
guard let r = root else {
return nil
}
var stack = [r]
while let node = stack.last {
let temp = node.left
node.left = node.right
node.right = temp
stack.removeLast()
if let left = node.left { stack.append(left) }
if let right = node.right { stack.append(right) }
}
return r
}
}

Reverse a linked list in Swift

Reversing a linked list in Swift is easy. I have a working solution. However, while preparing for whiteboard interviews the version I produce quickly simply does not work and I cannot identify why.
I need to know why the following does not work - from the Playground I believe it is because
tail = previous
line errors and execution never completes.
func reverseLL (node: Node?) -> Node? {
guard node != nil else { return nil }
var tail : Node? = node
var previous = node?.next
while previous != nil {
let tailRef = previous?.next
previous?.next = tail
tail = previous
previous = tailRef
}
return tail
}
My definition of the linked list is:
class Node: CustomStringConvertible {
var data: Int
var next: Node?
var description: String {
return String(data) + (next != nil ? next!.description : "")
}
init (data: Int) {
self.data = data
next = nil
}
func appendToTail(data: Int) {
if (next != nil) {
next?.appendToTail(data: data)
}
else {
next = Node(data: data)
}
}
}
My working version of reverseLL (which I accept is more 'Swifty') is as follows, but I believe it should be functionally identical to my earlier definition.
func reverseLL (node: Node?) -> Node? {
guard node != nil else { return nil }
var tail: Node?
var headNode = node
while let head = headNode {
let tailRef = head.next
head.next = tail
tail = head
headNode = tailRef
}
return tail
}
So creating a linked list with
let ll = Node(data: 3)
ll.appendToTail(data: 4)
ll.appendToTail(data: 4)
ll.appendToTail(data: 5)
gives the data in order of 3445
and reversed through
reverseLL(node: ll)
gives the data in order of 5443
To be clear, why does the
tail = previous
line halt execution in my first definition of reverseLL?
The second version is more Swifty since you're using optional binding and avoiding the horrendous forced-unwrapping.
The problem in the first version is that tail is initially equal to node. In the example that you've given that is (3->4->4->5).
So when you do previous?.next = tail in the first iteration, previous becomes (4->4->5->3->4->5->3->4->5->...). Notice that The node with data equal to 5 now points to a node with data equal to 3. Which creates an infinite loop.
Simplification
The guard statement could also be written as :
guard node?.next != nil else {
return node
}
which would include lists with a single node.
Here is the complete code including class, function and input and output things
// First we are creating class to store the data of Linked List
class Node {
var data: Int
var next: Node?
var description: String {
return String(data) + (next != nil ? next!.description : "")
}
init (data: Int) {
self.data = data
next = nil
}
func appendToLast(data: Int) {
if (next != nil) {
next?.appendToLast(data: data)
} else {
next = Node(data: data)
}
}
}
//Function that return the reversed Linked List
func reverseLinkedList(node: Node?) -> Node? {
guard node != nil else { return nil }
var tail: Node?
var headNode = node
while let head = headNode {
let tailRef = head.next
head.next = tail
tail = head
headNode = tailRef
}
return tail
}
//Input all the data which we have in the linkedlist and output of that inside the print function.
let ll = Node(data: 3)
ll.appendToLast(data: 4)
ll.appendToLast(data: 4)
ll.appendToLast(data: 5)
let reversedLL = reverseLinkedList(node: ll)
print(reversedLL?.description ?? "No Data")

Swift 3 delete nodes from singly linked list

I am trying to remove all elements from a linked list of integers that have value val. Is it necessary to set the removed nodes to nil to free memory?
func removeElements(_ head: Node?, _ val: Int) -> Node? {
var first = head
var current = head
var prev: Node?
while current != nil {
if current?.val != val {
prev = current
} else if current?.val == first?.val {
var oldFirst = first
first = current?.next
oldFirst = nil // is this line necessary?
} else {
prev?.next = current?.next // do I need to set current to nil?
}
current = current?.next
}
return first
}
oldFirst = nil only sets the variable in your current scope to nil.
Again, current is a variable in your local scope, it gets already dereferenced and thus cleaned up once you leave its scope.
If you have no strong references to an object anymore it is released by itself because Swift uses Automatic Reference Counting (ARC: https://en.wikipedia.org/wiki/Automatic_Reference_Counting)
I am not sure why you have the 2nd case in your code. I guess it checks the case where the current node has value val but you compare to first.val instead of val
func removeElements(_ head: ListNode?, _ val: Int) -> ListNode? {
guard head != nil else {
return nil
}
let preDummy = ListNode(val: 0), postDummy = ListNode(val: 0)
var pre = preDummy, node = head
while node != nil {
if node!.val == val {
postDummy.next = node?.next
node!.next = nil
} else {
pre.next = node
pre = node!
}
node = node!.next
}
pre.next = postDummy.next
return preDummy.next
}

Swift Dijkstra Algorithm Error (EXC_BAD_INSTRUCTION)

So I've built a swift playground that uses Dijkstra's algorithm to find the shortest route. However, I can't seem to manipulate my txt file so that my function will work in every case. It only works for a select few pathways. Whenever I map out a pathway I believe should work, it responds with: Execution was interrupted, reason: EXC_BAD_INSTRUCTION(code=EXC_I386_INVOP, subcode=0x0).
How can I manipulate my txt file or my function/file manipulation to take my txt file input? (Where error occurred is marked -- near the bottom)
Usually the error occurs when trying to build a route backwards.
Ex: a1 to a3 works
Ex: a3 to a1 does not work
Code:
import Foundation
// Extensions
extension Array {
func each<U>(closure:(Element)->U?)->U? {
for i in self {
let returnVal = closure(i)
if (returnVal != nil) { return returnVal }
}
return nil
}
}
extension Int {
func times(closure:(Int)->Void) {
for i in 0..<self { closure(i) }
}
}
// Structs
struct Edge {
var wt: Double
var desV: Room
}
struct Graph { var vertices:[Room] }
// Room Class
class Room: Hashable {
var name: String?
var neighbors: [Edge] = []
var hashValue: Int {
get { return name!.hashValue }
}
init(){}
convenience init(name:String) {
self.init()
self.name = name
}
func distanceToRoom(targetRoom:Room) -> Edge? {
return self.neighbors.each({ (edge:Edge) -> Edge? in
if (edge.desV == targetRoom) {
return edge
}
return nil
})
}
}
// Functions
func == (lhs:Room, rhs:Room) -> Bool { return lhs.hashValue == rhs.hashValue }
func say( a:String ) { print( a, terminator:"") }
func dijkstra(graph:Graph, target:Room) -> [Room:Room] {
var queue = graph.vertices
var distances:[Room:Double] = [:]
var previousPaths:[Room:Room] = [:]
let currentRoom:Room = queue[0]
queue.each {(element:Room) -> Void? in
distances[element] = Double.infinity
previousPaths[element] = nil
return nil
}
distances[currentRoom] = 0
while (queue.count > 0) {
var closestNode:Room? = nil
let wt:Double = Double.infinity
queue.each({ (Room:Room) -> Void? in
if (closestNode == nil || wt < distances[Room]!) {
closestNode = Room
}
return nil
})
if (closestNode! == target) {
return previousPaths
}
let nodeIndex:Int? = queue.indexOf(closestNode!)
queue.removeAtIndex(nodeIndex!)
if (closestNode?.neighbors != nil && closestNode?.neighbors.count > 0) {
closestNode?.neighbors.each({(neighbor:Edge) -> Void? in
let wt = distances[closestNode!]! + closestNode!.distanceToRoom(neighbor.desV)!.wt
if wt < distances[neighbor.desV] {
distances[neighbor.desV] = wt
previousPaths[neighbor.desV] = closestNode!
}
return nil
})
}
}
return previousPaths
}
// File Management
//let url = NSURL(string:"file:///Users/caleb/Documents/Xcode/CRHS/CRHS/dtb.txt")!
let url = NSURL(string: "file:///Users/caleb/Desktop/rooms.txt")!
let data = NSData(contentsOfURL: url)
let sdata = String(data: data!, encoding: NSUTF8StringEncoding)
let dataArray = sdata!.characters.split{$0 == "\n"}.map(String.init)
var rooms = [String:Room]()
print("data:\n-------")
for i in 0 ..< dataArray.count {
let conn = dataArray[i].characters.split{$0 == "\t"}.map(String.init)
var room1: Room
if ( rooms[conn[0]] == nil ) {
room1 = Room(name: conn[0])
} else {
room1 = rooms[conn[0]]!
}
let room2 = Room(name: conn[2])
let edwt = (conn[1] as NSString).doubleValue
var edge = Edge(wt: edwt, desV: room2)
if room1.neighbors.count == 0 {
room1.neighbors = [ edge ]
} else {
var found: Bool = false
for e in room1.neighbors {
if ( e.desV.name == edge.desV.name ) {
found = true
}
}
if ( found == false ) {
room1.neighbors.append(edge)
}
}
rooms[conn[0]] = room1
}
for (nam,room) in rooms {
print(nam)
print("----")
for n in room.neighbors {
if let un = n.desV.name {
print( un, terminator: " weight: ")
}
print( n.wt )
}
print("\n")
}
var namessofrooms = rooms.map { $0.0 }
var roomsofrooms = rooms.map { $0.1 }
print("Rooms:")
print(rooms)
print("-------\n")
// Calculating
var source = rooms["a1"]!
var target = rooms["a4"]!
roomsofrooms.append(source)
var reversedRooms: Array = roomsofrooms.reverse()
reversedRooms.append(target)
var graph = Graph(vertices: reversedRooms)
var paths = dijkstra(graph, target: target)
var pathVertices:[Room] = [target]
var child = target
while (child != source) {
print(child.name)
print(":::::")
child = paths[child]! //Error occurs here
print(child.name)
pathVertices.append(child)
}
var pathString:[String] = pathVertices.reverse().map { (Room:Room) -> String in
return Room.name!
}
print("solution:\n-------")
print(pathString)
Below is the file I input:
a1 1 a2
a2 1 a3
a3 1 a4
If I input the following file the code above will not work:
a1 1 a2
a2 1 a3
a3 1 a4
a4 1 a5
(Update: File Map Clarification)
First column is the first room, second is the weight between the rooms, third is the room connected to the first.

Finding the first non-repeating character in a String using Swift

This finds the duplicates in the array, but i'm looking for something that finds the first non-repeating character in a string. I've been trying to figure out a way to do this and I cannot figure it out. This is the closest i've gotten.
var strArray = ["P","Q","R","S","T","P","R","A","T","B","C","P","P","P","P","P","C","P","P","J"]
println(strArray)
var filter = Dictionary<String,Int>()
var len = strArray.count
for var index = 0; index < len ;++index {
var value = strArray[index]
if (filter[value] != nil) {
strArray.removeAtIndex(index--)
len--
}else{
filter[value] = 1
}
}
println(strArray)
In order to tell if a character repeats itself, go through the entire array once, incrementing the count of occurrences in a dictionary:
let characters = ["P","Q","R","S","T","P","R","A","T","B","C","P","P","P","P","P","C","P","P","J"]
var counts: [String: Int] = [:]
for character in characters {
counts[character] = (counts[character] ?? 0) + 1
}
let nonRepeatingCharacters = characters.filter({counts[$0] == 1})
// ["Q", "S", "A", "B", "J"]
let firstNonRepeatingCharacter = nonRepeatingCharacters.first!
// "Q"
Here is a simple solution
let inputString = "PQRSTPRATBCPPPPPCPPJ"
func nonRepeat (_ input: String) -> String {
for char in input {
if input.firstIndex(of: char) == input.lastIndex(of: char) {
return String(char)
}
}
return ""
}
print (nonRepeat(inputString))
In the above example it would print "Q"
func firstNonRepeatedCharacter(input: String) -> Character?{
var characterCount : [Character : Int] = [:]
var uniqueCharacter: Character?
for character in input{
if let count = characterCount[character]{
characterCount[character] = count + 1
if(uniqueCharacter == character)
{
uniqueCharacter = nil
}
}
else{
characterCount[character] = 1
if(uniqueCharacter == nil){
uniqueCharacter = character
}
}
}
return uniqueCharacter
}
Without extra loop to find character from characterCount dictionary
Here is the way I have found to detect the first non-repeated character. It removes spaces and punctuation to find the actual letter or number that does not repeat.
extension String {
func removeNonAlphaNumChars() -> String {
let charSet = NSCharacterSet.alphanumericCharacterSet().invertedSet
return self
.componentsSeparatedByCharactersInSet(charSet)
.joinWithSeparator("")
}
var firstNonRepeatedCharacter: Character? {
let alphaNumString = self.removeNonAlphaNumChars()
let characters = alphaNumString.characters
let count = characters.count
guard count > 0 else { return nil }
// Find unique chars
var dict: [Character: Int?] = [:]
for (index, char) in characters.enumerate() {
if dict[char] != nil {
dict[char] = (nil as Int?)
}
else {
dict[char] = index
}
}
return dict.filter { $0.1 != nil }.sort { $0.1 < $1.1 }.first?.0
}
}
I totally wonder why the accepted answer was considered correct. They are using
.first
method of a dictionary and that according to documentation would return a random element in the dictionary and not the first element as a dictionary in swift is not ordered like an array.
please do find below an implementation that works
func firstNonRepeatingLetter(_ str: String) -> String{
var characterDict = [String : Int]()
for character in str{
let lower = character.lowercased()
if let count = characterDict[lower]{
characterDict[lower] = count + 1
}else{
characterDict[lower] = 1
}
}
let filtered = characterDict.filter { $0.value == 1}
for character in str{
let lower = character.lowercased()
if let _ = filtered[lower]{
return lower
}
}
return ""
}
firstNonRepeatingLetter("moonmen") would return "e".
We can iterate once and keep the letter counts inside a dictionary.
Then, iterate again and return first letter where we see it was encountered once only (or "_" if not found a non-repeating letter):
func firstNotRepeatingCharacter(s: String) -> Character {
var letterCounts: [String: Int] = [:]
var result: Character = "_"
for letter in s {
if let currentLetterCount = letterCounts[String(letter)] {
letterCounts[String(letter)] = currentLetterCount + 1
} else {
letterCounts[String(letter)] = 1
}
}
for letter in s {
if letterCounts[String(letter)] == 1 {
result = letter
break
}
}
return result
}
OrderedDictionary makes this easy for all Sequences of Hashables, not just Strings:
import struct OrderedCollections.OrderedDictionary
extension Sequence where Element: Hashable {
var firstUniqueElement: Element? {
OrderedDictionary(zip(self, true)) { _, _ in false }
.first(where: \.value)?
.key
}
}
/// `zip` a sequence with a single value, instead of another sequence.
public func zip<Sequence: Swift.Sequence, Constant>(
_ sequence: Sequence, _ constant: Constant
) -> LazyMapSequence<
LazySequence<Sequence>.Elements,
(LazySequence<Sequence>.Element, Constant)
> {
sequence.lazy.map { ($0, constant) }
}
func getFirstUniqueChar(string:String)->Character?{
var counts: [String: Int] = [:]
for character in string {
let charString = "\(character)"
counts[charString] = (counts[charString] ?? 0) + 1
}
let firstNonRepeatingCharacter = string.first {counts["\($0)"] == 1}
return firstNonRepeatingCharacter
}
print(getFirstUniqueChar(string: string))
import Foundation
import Glibc
var str:String = "aacbbcee"//your input string
var temp:String = ""
var dict:[Character:Int] = [:]
for char in str{
if let count = dict[char]{
dict[char] = count+1//storing values in dict and incrmenting counts o key
}
else{
dict[char] = 0
}
}
var arr:[Character] = []
for (key, value) in dict{
if value == 0{
arr.append(key)//filtering out, take characters which has value>0
} //int(arr)
}//print(arr.count)
if arr.count != 0{
outer:for char in str{//outer is labeling the loop
for i in arr{
if i == char{
print(i,"is first")//matching char with array elements if found break
break outer
}
else{
continue
}
}
}
}
else{
print("not found")
}
func firstNonRepeatedChar(string: String) -> Character {
var arr: [Character] = []
var dict: [Character : Int] = [:]
for character in string.description {
arr.append(character)
}
for character in arr {
dict[character] = (dict[character] ?? 0) + 1
}
let nonRepeatedArray = arr.filter { char in
if dict[char] == 1 {return true}
return false
}
let firstNonRepeatedChar = nonRepeatedArray.first
return firstNonRepeatedChar!
}
print(firstNonRepeatedChar(string: "strinstrig"))