↳
let givenArray = [1,0,2,0,0,3,4] var arrayWithNonZeroElements = givenArray.filter({ $0 != 0 }) let arrayWithZeroElements = givenArray.filter({ $0 == 0 }) print(arrayWithNonZeroElements.count) //"4\n" arrayWithNonZeroElements.appendContentsOf(arrayWithZeroElements) print(arrayWithNonZeroElementst) // [1,2,3,4,0,0,0] Less
↳
The answer from OP is good, but there is a case where it doesn't work : if the last value of the array is @0 and the array contains another @0 (Ex: [@1, @0, @2, @0], then you end up swapping two @0 and not solving fully the problem. There is a little optimization possible on the ending condition of the for loop : ending when we reach exchangeObjectAtIndex:indexOfLastNonZeroItem instead. Here is my full solution : - (NSInteger) countAndRearrangeNonZeroElementsFromThisArray: (NSMutableArray*) originalArray { NSInteger countOfZeros = 0; NSInteger indexOfLastNonZeroItem = [originalArray count] - 1; while ([originalArray[indexOfLastNonZeroItem] isEqualToNumber: @0]) { indexOfLastNonZeroItem--; } for(NSInteger index = 0; index < indexOfLastNonZeroItem; index++) { NSNumber * numberFromArray = [originalArray objectAtIndex:index]; if([numberFromArray isEqualToNumber:@0]){ countOfZeros++; [originalArray exchangeObjectAtIndex:index withObjectAtIndex:indexOfLastNonZeroItem]; indexOfLastNonZeroItem--; } } return countOfZeros; } Less
↳
modified version of the above answer, that works with inout arrays func countZerosAndMoveToBegning(array: inout [String]) -> UInt { let nonZeros = array.filter { $0 != "0" } let zeros = array.count - nonZeros.count let arrayZeros = Array(repeating: "0", count: zeros) array.removeAll() array.append(contentsOf: arrayZeros) array.append(contentsOf: nonZeros) return UInt(zeros) } Less
↳
-(int)sortZerosAndReturnCountOfThem:(NSMutableArray *)arr { NSLog(@"before: %@", arr); int cursorFromStart = 0; int cursorFromEnd = (int)arr.count - 1; while (cursorFromStart < cursorFromEnd) { while (arr[cursorFromStart].intValue != 0) { cursorFromStart++; } while (arr[cursorFromEnd].intValue == 0) { cursorFromEnd--; } if (cursorFromStart < cursorFromEnd) { arr[cursorFromStart] = arr[cursorFromEnd]; arr[cursorFromEnd] = @(0); } } NSLog(@"after: %@", arr); int counter = 0; for (NSNumber *num in arr) { if (num.intValue == 0) { counter++; } } NSLog(@"counter: %d", counter); return counter; } Less
↳
func moveZeros(input: inout [Int]) -> Int { //reverse sort input = input.sorted { $0 > $1 } let countNonZero = input.filter { $0 != 0 }.count return countNonZero } Less
↳
No need to sort. Can do in O(n) time. Swift: func moveAllZerosToFront(list: inout [Int]) -> Int { var numOfZeros = 0 for i in 0.. Less
↳
The idea is if we traverse binary search tree "in-order", output of number is in ascending orders. So here it goes. Not checked for syntax errors, but should work. BOOL Inorder(NODE *node) { static NODE *prev = NULL; // Do need to initialize this as statics are zeroed memory. if (node == NULL) { return true; } if (false == Inorder(node->left)) { return false; } if (prev && node->num num) { return false; } prev = node; return Inorder(node->right); } Less
↳
A simpler approach is to do an inorder traversal keeping track of last seen element. If it is always increasing then we can prove that tree is BST. Less
↳
class TreeNode { var value: Int? var leftChild: TreeNode? var rightChild: TreeNode? } func isBST(node: TreeNode, min: Int, max: Int) -> Bool { print("value: " + String(node.value!)) print("min: " + String(min)) print("max: " + String(max)) if node.value! max { return false } if let leftChild = node.leftChild { if isBST(leftChild, min: min, max: node.value!) == false { return false } } if let rightChild = node.rightChild { if isBST(rightChild, min: node.value!, max: max) == false { return false } } return true } // Creating BST let minValue = Int.min let maxValue = Int.max let node2 = TreeNode() node2.value = 2 node2.leftChild = nil node2.rightChild = nil let node7 = TreeNode() node7.value = 7 node7.leftChild = nil node7.rightChild = nil let node11 = TreeNode() node11.value = 11 node11.leftChild = nil node11.rightChild = nil let node15 = TreeNode() node15.value = 15 node15.leftChild = nil node15.rightChild = nil let node5 = TreeNode() node5.value = 5 node5.leftChild = node2 node5.rightChild = node7 let node13 = TreeNode() node13.value = 13 node13.leftChild = node11 node13.rightChild = node15 let node10 = TreeNode() node10.value = 10 node10.leftChild = node5 node10.rightChild = node13 if isBST(node10, min: minValue, max: maxValue) == true { print("Tree is BST.") }else { print("Tree is not BST.") } Less
↳
There is a built in class that already does this. Just use that. NSArray *array; // input array NSArray *result = [[NSOrderedSet orderedSetWithArray:array] array]; Less
↳
the question answered above are definitely not optimized but easy built in function, I doubt thats what the interviewer want, if it's sorted array, it will be easy, we simply keep track of the current number, remove duplicate and move forward, but if it's not sorted, then I think a NSMutableDictionary would be efficient to perform a one time scan from begin to the end, so it's O(n) time and O(n) space. Less
↳
Is it alright if we use NSOrderedSet? Or do they expect you to solve it without using the built-in components. Because with NSOrderedSet, it can be solved in 1 line. Less
↳
swift solution using bucket sort func sortZeroesAtEnd(in array: [Int]) -> [Int] { //pseudo bucket sort var zeroBucket: [Int] = [] var nonZeroBucket: [Int] = [] for n in array { if n == 0 { zeroBucket.append(n) } else { nonZeroBucket.append(n) } } return nonZeroBucket + zeroBucket } Less
↳
var array = [8, 4, 3, 0, 6, 4, 0] var offset = 0 for index in stride(from: array.count - 1, through: 0, by: -1) { if array[index] == 0 { offset += 1 } else { array[(index + offset)] = array[index] if index < offset { array[index] = 0 } } } // result: [0, 0, 8, 4, 3, 6, 4] Less
↳
func moveZerosToFront(array: [Int]) -> [Int] { var resultArray = [Int]() for num in array { num == 0 ? resultArray.insert(0, at: 0) : resultArray.append(num) } return resultArray } Less
↳
- (nullable UIView *)commonSuperview:(nullable UIView *)otherView { if(!otherView) return nil; NSMutableArray* superViewsArray = [NSMutableArray array]; UIView* superVeiw = self; while (superVeiw) { [superViewsArray addObject:superVeiw]; superVeiw = superVeiw.superview; } superVeiw = otherView; while (superVeiw) { if([superViewsArray containsObject:superVeiw]){ break; } superVeiw = superVeiw.superview; } return superVeiw; } Less
↳
extension UIView { func sameSuperview(other: UIView) -> UIView? { guard self.superview != nil || other.superview != nil else { return nil } var superViews: [UIView] = [] //Should be a set var selfSuperView = self.superview while selfSuperView != nil { superViews.append(selfSuperView!) selfSuperView = selfSuperView!.superview } selfSuperView = other.superview while selfSuperView != nil { if superViews.contains(selfSuperView!) { return selfSuperView } selfSuperView = selfSuperView!.superview } return nil } } Less
↳
- (UIView *)commonSuperView:(UIView *)oneView anotherView:(UIView *)anotherView { if (!oneView || !anotherView) { return nil; } NSMutableArray *viewArray = @[oneView].mutableCopy; while (oneView.superview) { oneView = oneView.superview; [viewArray addObject:oneView]; } if ([viewArray containsObject:anotherView]) { return anotherView; } while (anotherView.superview) { anotherView = anotherView.superview; if ([viewArray containsObject:anotherView]) { return anotherView; } } return nil; } Less
↳
Since nobody answered regarding the UiView tree question, posting my solution that I finished only after the interview: -(void)originalInput { UIView *B = [UIView someViewWithParentAndChildren]; //known subview UIView *a = [UIView someViewWithParentAndChildren]; //root of clone view tree NSMutableArray *indexPaths = [NSMutableArray new]; [self recordIndexPaths:indexPaths fromView:B]; //creating index array UIView *cloneViewB = [self findViewByIndexes:indexPaths forIndex:0 forView:a]; //recursing through the clone view hierarchy NSLog(@"%@", cloneViewB); } -(void)recordIndexPaths:(NSMutableArray *)indexPaths fromView:(UIView *)view { if (view.parent == nil){ return; }else { UIView *parent = view.parent; int i = [parent.children indexOfObject:view]; [indexPaths insertObject:i atIndex:0]; //i is not and object, but primitive, should be incapsulated in NSNumber in real life!! [self recordIndexPaths:indexPaths fromView:parent]; } } -(UIView *)findViewByIndexes:(NSArray *)indexPaths forIndex:(int)i forView:(UIView *)currentView { if (!currentView.children.count) return currentView; int j = indexPaths[i]; //j is not and object, but primitive, should be incapsulated in NSNumber in real life!! UIView *child = currentView.children[j]; return [self findViewByIndexes:indexPaths forIndex:i+1 forView:child]; } Less
↳
// We just need to find the path to the main top superview on the original view, saving the index of each view based on its superview and then reverse the path and search on the cloned view. func findView(_ view: UIView, in clonedView: UIView) { var path = [Int]() var view: UIView? = view while view != nil { let tmp = view! view = view!.superview if let idx = view?.subviews.index(of: tmp) { path.append(idx) } } view = clonedView for idx in path.reversed() { view = view?.subviews[idx] } print("Cloned view is: \(view!.tag)") } Less
↳
func removeDups(words: [String], caseSensitive: Bool = false) -> [String] { var hashtable = Dictionary() var words2 = [String]() for word in words { let hash = (caseSensitive ? word : word.uppercased()).hashValue hashtable[hash] = (hashtable[hash] ?? 0) + 1 if hashtable[hash] == 1 { words2.append(word) } } return words2 } Less
↳
[1,[4,3],6,[5,[1,0]]] -(void)printOutLinearly:(NSArray *)inpA { if (!inpA.count) NSLog(@”There’s nothing in this array you silly willy”); for (int i=0; i < inpA.count; i++) { if ([inpA objectAtIndex:i] isKindOfClass:[NSArray class]]) { [self printOutLinearly:[inpA objectAtIndex:i]; } else { NSLog(@”%@”,[inpA objectAtIndex:i]; } } } Less
↳
Used an array ivar as a stack to maintain state.
↳
func flattenArray(nestedArray: [Any]) -> [Int] { var myFlattenedArray = [Int]() for element in nestedArray { if element is Int { myFlattenedArray.append(element as! Int) } else if element is [Any] { let recursionResult = flattenArray(nestedArray: element as! [Any]) for num in recursionResult { myFlattenedArray.append(num) } } } return myFlattenedArray } Less
↳
Delete all 0s while counting them, and then add them to the end. func moveZerosToTheEndInArray(_ array: inout Array) -> Array { var counter = 0 array = array.filter({ (arrayElement) -> Bool in print(arrayElement) if arrayElement == 0 { counter += 1 print("Increment counter because arrayElement is \(arrayElement)") return false } print("return true because arrayElement is \(arrayElement)") return true }) print(array) print(counter) for _ in 0.. Less
↳
func sortedZeroToEnd(_ arr:[Int]) -> [Int] { return arr.sorted{ $0 > $1 } } Less
↳
What about : let arr = [ 3, 0, 2, 0, 0, 4, 1, 0 ] let res = arr.filter( {$0 != 0} ) + arr.filter( {$0 == 0} ) OR let arr = [ 3, 0, 2, 0, 0, 4, 1, 0 ] var res = arr.filter( {$0 != 0} ) res += Array(repeating: 0, count: arr.count - res.count) Less
↳
It depends on the application. Is it CPU-bound or I/O-bound? 1. Check all I/O that the application does: look at I/O speeds, blocking vs. non-blocking calls, see how much time CPU is waiting on I/O using iostat. 2. If I/O is ok, look at CPU usage. Profile the application: look at function call timings, see if any function call is taking abnormally long. Look at garbage collection that may be more frequent if program is using a lot of memory, perhaps due to a memory leak. Less
↳
@Vishal, I've always heard the first rule of performance optimization is don't - until you're absolutely sure what needs to change. Randomly changing code/guessing is a great way to waste time and possibly make things worse, or not find any gains. Profile, analyze, figure out where the time is spent before touching any code! TI's response is the best one I think. Less
↳
I don't know