CS354: Operating Systems

advertisement

CS252: Systems Programming

Ninghui Li

Program Interview Questions

String Problem

• Input is a string containing a set of words separated by white space(s). Write a function that will transform it to a string in which the words appear in the reverse order. For example " this is really good " becomes " good really is this ".

• We require that only a constant amount of extra space, and linear time is used.

String Problem Solution

Solution: two-pass processing

First pass reverse whole string

Second pass, find each word and reverse it locally

Similar Problem

• Consider strings over alphabet {a,b,c,d}, write a function that takes an input string, and

(1) removes each “b”, (2) replaces each “a” by “dd”, and does so in place (assume the string is in a buffer long enough for the result) using constant additional storage.

Linked List: Deletion from a

Singly Linked List

• Given a singly linked list, you are given one node and are asked to delete it from the list.

• You are asked to do it in constant time.

• What is the challenge?

• This is possible when the node is not the last node in the list, and copying the data field in the node takes constant time.

• How?

Linked List: Checking for

Cyclicity

• Although a linked list is supposed to end with NULL, it is possible to have it points to another element in the list, creating a cycle

• Write code to check whether a singly linked list ends in NULL or contains a cycle

• C1: no modifying the list.

C2: constant extra space.

• C3: linear time running time

How to find the first element of the cycle?

Linked List: Checking for

Cyclicity

• Solution 1: Satisfies C2, C3; violate C1;

• Remember the head, reverse the linked list as one traverses it, and report cycle if one reaches the head node again.

• Solution 2: Satisfies C2, C3; violates C1; assumes that there is a bit in the data structure that is initialized to 0

Linked List: Checking for

Cyclicity

• Solution 3: Satisfies C1, C3; violate C2;

• Record all visiting nodes in a hash table, and do a lookup for each newly encountered node.

• Solution 4: Satisfies C1, C2; violates C3;

• For each newly encountered node, check whether its next will be visited if one starts from head again and try to traverse to current node.

Linked List: Checking for

Cyclicity

• Solution 5: Satisfies C1, C2, C3;

• Uses 2 pointers. One fast and one slow. Fast one advances two steps each time, and show one advances one step each time, they meet if and only if there is a cycle.

• To figure out where cycle starts,

• First figure out cycle length X, and pinning fast pointer, and count how many steps it takes slow pointer to meet fast

• Then set fast pointer at position X, and slow at beginning, advance both at 1 step at a time, when they meet, slow is pointing at beginning of cycle

Additional LinkedList Problem

• How to find the middle of a linked list in one pass of the linked list?

Tower of Hanoi

• Move n rings stacked on Peg 1 (rings are from small to large from top to bottom) to

Peg 2,

• Peg 3 is empty.

• Write a program to output the necessary steps to move n rings on Peg 1 to Peg 2.

Implementing a Queue with two

Stacks

• Queue (FIFO) supports two operation

• enqueue (add an element)

• dequeue (remove the first added element)

• Stack (LIFO) supports two operations

• push (add an element)

• pop (remove the last added element)

• How to implement a queue using two stacks?

Implementing a Queue with two

Stacks

Enqueue(e) { stack1.push(e);

}

Dequeue(){ if (stack2.isEmpty()) { while(! stack1.isEmpty()) { stack2.push(stack1.pop());

} return stack2.pop();

}

Implement a Reentrant (or

Recursive) Lock

If a thread currently holding the lock tries to lock it again, for a non-reentrant or nonrecursive lock, we have a deadlock

A reentrant (or recursive) lock allows the thread to proceed; the thread must unlock it correct number of times for other process to obtain the lock

Big Data with Limited Memory

Given an input file with four billion nonnegative integers, provide an algorithm to generate an integer which is not contained in the file. Assume you have 1GB of memory available for this task.

Use a bit vector, each bit to represent whether an integer is present; this requires 2^31 bit, or about 256M bytes.

Taken from Gayle Laakmann McDowell: “Cracking the Coding

Interview”, 5 th Edition.

Big Data with Memory Limit

(continued)

What if you have only 10MB of memory?

Assume that for input you have no more than one billion non-negative integers, and they are all distinct.

First scan determines # of integers in each thousands, e.g., between 0 and 1023, 1024 and 2047, etc.

Find a region that is not full, second scan finds a number in that region

What if the integers are not guaranteed to be distinct?

Taken from Gayle Laakmann McDowell: “Cracking the Coding

Interview”, 5 th Edition.

Hash Table

How to design a hash function for words in a dictionary, e.g., for use in a hash table of size N?

What makes a good hash function?

Distribution of output is close of uniform over

[0..N-1].

Is sum of all characters a good hash function?

Is product of all characters a good hash function?

Anagrams

Two words are anagrams if they contain the same set of characters.

Write a program to partition a dictionary into sets of words such that all words in each set are anagrams.

Divide and Conquer

Recursively

Divide: break down the problem into two or more sub problems:

Conquer: solve the sub problems, and then combine their results

Example: Merge sort

Divide and Conquer Question

Compute the number of reversed pairs in an array A of numbers. A pair (i,j) is reversed if A[i]>A[j].

Solution idea (do merge sort while computing this):

# of inverse in whole = # of inverse in left half

+ # of inverse in right half

+ # of inverse involving one element in left and one in right (can be computed while merging left and right)

Code available https://github.com/adnanaziz/EpiCode/blob/master/Java/com/epi/CountIn versions.java

Divide and Conquer Question

Diameter of a tree

Consider a tree where each edge has a number

(distance), compute the maximal distance between two leaf nodes.

Solution Idea:

For each internal node, computes the max distance as well as the max height

Pseudo Code

max_dist(node *p, &dt, &ht) { // dt:distance, ht:height int cd, ch, ht2=0, nht; // ht2 stores second highest height

*dt=0; *ht=0; if (p is leaf) return; for each child c of p { max_dist(c, &cd, &ch); if (cd>*dt) *dt=cd; // current max distance is from subtree at c nht = ch + e(c); // e(c) is distance on the edge to child c if (nht > *ht) { ht2 = *ht; *ht = nht;} else if (nht > ht2) { ht2 = nht; } if (ht2>0 && *ht+ht2>*dt) { *dt = *ht+ht2; }

// current max distance from leafs in two subtrees

}

}

Download