Flatten a recursive Linked List in Objective-C

Given a linked list, where each node’s value can itself be a linked list (a recursive linked list), write a function that flattens it. Final code at Github

Original Link List

Pretty difficult coding questions. First I tried a recursive solution that for some reason wasn’t working for all cases and then I came up with this one.

First of all let’s declare our Node Class with properties data – can have nil or another linked list, next – pointer to a next node and name – for debugging purposes.

@interface LLNode : NSObject;

@property id data;
@property LLNode *next;
@property NSString *name;

@end

@implementation LLNode

-(instancetype)initWithName:(NSString*)name{
    self = [super init];
    if(self)
    {
        self.name = name;
    }
    return self;
}

We will have a helper function that takes in a node and insert it’s data Linked list after it.

-(void)insertListAfterNode:(LLNode*)node{
    if (!node.data)
        return;
    else{
        LLNode *tempNext = node.next;
        node.next = node.data;
        node.data = nil;
        while (node.next)
            node = node.next;
        node.next = tempNext;
    }
}

And the final function is to go through the linked list and insert all child linked lists in a row.

-(void)processLinkedList:(LLNode*)root{
    LLNode *pointer = root;
    while (pointer.next) {
         [self insertListAfterNode:pointer];
        pointer = pointer.next;
    }
}

At the end we should have linked list flattened.
Flattened Linked List

Sherlock and Array – Question from hackerrank

Just finish a fun question from Hackerrank: Sherlock and Array
Question description:

Watson gives Sherlock an array AA of length NN. Then he asks him to determine if there exists an element in the array such that the sum of the elements on its left is equal to the sum of the elements on its right. If there are no elements to the left/right, then the sum is considered to be zero.
Formally, find an ii, such that, AA1+A+A2…A…Ai-1 =A=Ai+1+A+Ai+2…A…AN.

My approach is to go through array and on each iteration adjust sum on the left and sum on the right by current integer from array. Complexity of this approach is O(n). Code below:

#import <Foundation/Foundation.h>

int main (int argc, const char * argv[]) {

    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

    int numberOfTestCases;
    scanf("%d", &numberOfTestCases);
   
    for (int i=0; i<numberOfTestCases; i++) {
         NSMutableArray *inputIntegers = [NSMutableArray new];
        BOOL sumExists = NO; 
        int numberOfElements;
        int sumLeft = 0;
        int sumRight = 0;
        scanf("%d", &numberOfElements);
        for (int j=0; j<numberOfElements; j++) {
            int inputElement;
            scanf("%d", &inputElement);
            [inputIntegers addObject:[NSNumber numberWithInt:inputElement]];
            sumRight+=[inputIntegers[j] integerValue];
        }
       
        for (int j=0; j<numberOfElements; j++) {
            sumRight -= [inputIntegers[j] integerValue];
            if (sumLeft == sumRight){
                sumExists = YES;
                break;
            } else {
                sumLeft += [inputIntegers[j] integerValue];
            }
        }
        printf("%s\n", sumExists ? "YES" : "NO");
    }

);

    [pool drain];
    return 0;
}

Coding question print binary tree by level in Objective C

This question was previously asked on the Facebook interview.
Given input as a binary tree print to console each level followed by new line character.
Input: Tree
Output:
“A\n
BC\n
DEF”

Solution: Do a breadth first search algorithm on a graph which will go over an entire tree and will build a resulted string.
First of all let’s create a custom class Node:

@interface Node : NSObject

@property NSObject *left;
@property NSObject *right;
@property NSString *value;

@end

Second let’s extend NSMutableArray with our own queue methods:

@interface  NSMutableArray (QueueAdditions)
- (id) dequeue;
- (void) enqueue: (id)obj;
@end

@implementation  NSMutableArray (QueueAdditions)

- (id) dequeue {
    id headObject = [self objectAtIndex:0];
    if (headObject != nil) {
        [self removeObjectAtIndex:0];
    }
    return headObject;
}

- (void) enqueue:(id)obj{
    [self addObject:obj];
}
@end

Add the function that will traverse over the graph and will build a resulted string:

+(NSString*) printTree:(Node*)node{
    
    if (node == nil){
        return @"";
    }
    
    NSMutableString *result = [[NSMutableString alloc] init];
    NSMutableArray *queue = [[NSMutableArray alloc] init];
    [queue enqueue:node];
    [queue enqueue:[NSNull null]];
    while (true){
        Node *curObject = [queue dequeue];
        if ([curObject isEqual:[NSNull null]]){
            [result appendString:@"\n"];
            
            if ([queue count] == 0){
                break;
            }
            [queue addObject:[NSNull null]];
            continue;
        }
        [result appendString:curObject.value];
        
        if (curObject.left){
            [queue enqueue:curObject.left];
        }
        if (curObject.right){
            [queue enqueue:curObject.right];
        }
    }
    
    return result;
}

code at gitlab: https://github.com/svetdev/print-tree-by-level

Recursively revert an array in Objective C

It’s a question that my fried received on a phone interview with one of the tech companies from West Coast
Let’s do it! We will create a function reverseAnArray that takes a NSMutableArray and return void.
+(void) reverseAnArray:(NSMutableArray *)input;

1. Set up a base – once we reach the end of the array we will return;

2. Temporary save first object and remove it from array

3. Call recursion again on a smaller array

4. Return from recursive call and put the saved object back in the array.

Final code:

+(void) reverseAnArray:(NSMutableArray *)input {

    if ([input count] == 0)
        return;
    
    NSObject *temp = [input objectAtIndex:0];
    [input removeObjectAtIndex:0];
    
    [self reverseAnArray:input];
    [input addObject:temp];
    
    return ;
}

Testing results

 NSMutableArray *input = [[NSMutableArray alloc] initWithArray:@[@2,@1,@3,@4,@6,@7,@8,@9]];
        NSLog(@"input is: %@", input);
        [Solution reverseAnArray:input];
        NSLog(@"output is: %@", input);

2016-02-08 14:06:41.944 UniqueElements[34000:2143133] input is: (
2,
1,
3,
4,
6,
7,
8,
9
)
2016-02-08 14:06:41.946 UniqueElements[34000:2143133] input is: (
9,
8,
7,
6,
4,
3,
1,
2
)

Done

Difference between formal and informal protocols

An informal protocol is a Category on NSObject. Implementation of the methods is optional.

@interface NSObject(NSApplicationNotifications)
- (void)applicationWillFinishLaunching:(NSNotification *)notification;
...
@interface NSObject(NSApplicationDelegate)
- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender;
...

Formal protocols are an Extension to the Objective-C language. Methods can be required or optional.

@protocol YourElementsViewDataSource
- (NSUInteger)numberOfElements;
- (CGFloat)sizeOfElementAtIndex:(NSUInteger)segmentIndex;
@optional
- (NSString *)titleForElementAtIndex:(NSUInteger)segmentIndex;
- (BOOL)shouldExplodeElementAtIndex:(NSUInteger)segmentIndex;
@required
- (UIColor *)colorForElementIndex:(NSUInteger)segmentIndex;
@end

This example defines a protocol with three required methods and two optional methods.

Difference between shallow copy and deep copy

Shallow copy only copies a memory address. Changing one object will also change another.

NSMutableArray *firstArray = [[NSMutableArray alloc] initWithObjects:@1, @2, @3, nil];
NSMutableArray *secondArray = [[NSMutableArray alloc] initWithObjects:@4, @5, @6, nil];
secondArray = firstArray;
[secondArray setObject:@9 atIndexedSubscript:0];
NSLog(@"%@", [firstArray objectAtIndex:0]); //9 the value in a first array has also changed

Deep copy copies the whole object. This process is slower, but both objects have their own copies, so changes in one will not affect another.

NSMutableArray *firstArray = [[NSMutableArray alloc] initWithObjects:@1, @2, @3, nil];
NSMutableArray *secondArray = [[NSMutableArray alloc] initWithObjects:@4, @5, @6, nil];
secondArray = [firstArray mutableCopy];
[secondArray setObject:@9 atIndexedSubscript:0];
NSLog(@"%@", [firstArray objectAtIndex:0]); //1 the value in a first array has not changed