Swift 3 delete nodes from singly linked list - swift

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
}

Related

Binary Tree Upside Down

The output from my code return an empty array while trying to put a binary tree upside down using dfs recursion. How do I fix this ?
public class TreeNode {
var val :Int
var left: TreeNode?
var right: TreeNode?
public init(_ val: Int, _ left: TreeNode?, _ right: TreeNode?) {
self.val = val
self.left = left
self.right = right
}
func upsideDownBinaryTree(_ root: TreeNode?) -> TreeNode? {
return dfs(current: root)
}
func dfs( current: TreeNode?) -> TreeNode? {
if current == nil {
return nil
}
let newRoot = dfs(current: current?.left)
current?.left?.left = current?.right
current?.left?.right = current
current?.left = nil
current?.right = nil
return newRoot
}
}
enter image description here
The problem is at the base case of recursion: it will always return nil. Since any other returned value is exactly the same as what was retrieved from the recursive call (newRoot), it can never be anything else than nil. There is no way the function can return anything else than nil.
Realise that the case current == nil is only there to deal with an empty tree. In all other cases the recursion should stop one step earlier: when it is a node without left child. In that case that node should be returned.
So change:
if current == nil {
return nil
}
To:
if current?.left == nil {
return current
}
Now the base case is focussed on the non-presence of the left child, and in that case the node itself will be returned. The case where current itself is nil is only relevant when the tree is empty, but it is also covered here.

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 Linked List Remove Duplicates

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

swift anonymous function recursion

I'm trying to write a function literal in swift with a recursive body - in this case it's simply to add all the values in a list. I'm getting an error that "Variable used within it's own initial value". Any thoughts on what might be wrong here? Also I'm aware that what I'm doing here is a simple reduce and that it's build into Array, I'm just using this as an illustrative example of what I'm seeing elsewhere.
let list: Slice = [1,2,3,4,5,6,7,8,9,10]
var closure = { (memo: Int, list: Slice<Int>) -> Int in
if (list.count == 0) {
return memo
} else {
return closure(memo + list[0], list[1..<list.count])
}
}
let value = closure(0,list)
Try this:
let list: Slice = [1,2,3,4,5,6,7,8,9,10]
var closure:((Int, Slice<Int>) -> Int)!
closure = { (memo, list) in
if (list.count == 0) {
closure = nil // remove retain cycle
return memo
} else {
return closure(memo + list[0], list[1..<list.count])
}
}
let value = closure(0, list)
EDIT:
see this video: Advanced Swift at WWDC14. from around 41:00. it shows the down side of this method, and better workaround.
I know this is quite old, but I've found another alternative:
let list : ArraySlice<Int> = [1,2,3,4,5,6,7,8,9,10]
let closure = { (Void) -> ((Int, ArraySlice<Int>) -> Int) in
func f(memo: Int, list: ArraySlice<Int>) -> Int {
if (list.count == 0) {
return memo
} else {
return f(memo + list[list.startIndex], list: list[(list.startIndex + 1)..<list.endIndex])
}
}
return f
}()
let value = closure(0, list)