大提莫


  • 首页

  • 分类

  • 关于

  • 归档

  • 标签

  • 搜索

random interviews: identify the heavy ball

发表于 2017-04-08 | 分类于 面经题

Given an array with 100 balls (each ball is to be imagined as an element in the array). 99 are of same weight only 1 is not. Identify the ball.

解法1:

Java

1

random interviews: shortest path in a matrix

发表于 2017-04-08 | 分类于 面经题

The task was to find the shortest path between x1,y1 and x2,y2 in a maze. You can move horizontally and vertically, where 1 is a wall and 0 is free space. output is k shortest steps to move from the start point to end point.

解法1:BFS

典型的BFS题目,用一个queue来解决。同时标记每一个已经visit过的元素的parent

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
Java
{% codeblock lang:java %}
public List<List<Integer>> shortestPath(int[][] maze, int[] start, int[] end) {
List<List<Integer>> res = new ArrayList<List<Integer>>();
if (maze == null || maze.length == 0 || maze[0].length == 0) {
return res;
}
if (start[0] == end[0] && start[1] == end[1]) {
List<Integer> temp = new ArrayList<Integer>(Arrays.asList(start));
res.add(temp);
return res;
}
int row = maze.length;
int col = maze[0].length;
// Use a map to store each point's shortest parent from the start point
Map<List<Integer>, List<Integer>> map = new HashMap<List<Integer>, List<Integer>>();
int[][] directions = {{1,0},{-1,0},{0,1},{0,-1}};
List<Integer> temp = new ArrayList<Integer>(Arrays.asList(start));
map.put(temp, null);
Queue<List<Integer>> queue = new LinkedList<List<Integer>>();
queue.offer(temp);
maze[start[0]][start[1]] = -1;
while(!queue.isEmpty()) {
int size = queue.size();
for (int i = 0; i < size; ++i) {
List<Integer> cur = queue.poll();
for (int j = 0; j < directions.length; ++j) {
int x = cur.get(0) + directions[j][0];
int y = cur.get(1) + directions[j][1];
if (x >= 0 && x < row && y >= 0 && y < col && maze[x][j] != -1) {
ArrayList<Integer> temp = new ArrayList<Integer>(Arrays.asList(x,y));
if (x == end[0] && y == end[1]) {
// find the destination
res = getPath(map, temp);
return res;
}
queue.offer(temp);
map.put(temp, cur);
maze[x][y] = -1; // mark as visited
}
}
}
}
return res;
}
private List<List<Integer>> getPath(HashMap<List<Integer>, List<Integer>> map, List<Integer> end) {
List<List<Integer>> res = new ArrayList<List<Integer>>();
List<Integer> cur = end;
while(map.get(cur) != null) {
res.add(cur);
cur = map.get(cur);
}
return res;
}
{% endcodeblock %}

random interviews: create a file system

发表于 2017-04-08 | 分类于 刷题总结

Design a file system. Write code for file, directory and all necessary classes.

解法1:

这下面的解法来源于这个career cup上的回答
A file system can be represented with a Tree data structure. We can have one class called file (a directory is also a file). This class can track its current directory, its parent directory and files in this directory (in case this file is a special file called directory). Then we can create a class to manage file system which is manipulating the nodes of the tree.

Java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
package filesystem;
import java.util.ArrayList;
import java.util.Date;
public class FileSystem {
public class file {
private String name;
private long size;
private Date timeStamp;
private file currentDir;
private file parentDir;
// a directory is also a file containing reference to other files
private boolean isDirectory;
public ArrayList<file> subfiles;
// Advanced class members if required
private boolean[] permissions;
private String owner;
private String group;
public file(String name, file currentDir, boolean isDir) {
this.name = name;
this.currentDir = currentDir;
this.timeStamp = new Date();
this.isDirectory = isDir;
this.size = 0; // initial size
this.parentDir = currentDir.getParentDirectory();
if (isDir == true)
this.subfiles = new ArrayList<file>();
}
public void updateTimeStamp() {
this.timeStamp = new Date();
}
public file getParentDirectory() {
return this.parentDir;
}
public void rename(String name) {
this.name = name;
}
}
private file root; // root folder
public FileSystem() {
// every file system should have a root folder
this.root = new file("root", null, true);
}
public void createFile(String name, file curDir, boolean isDir) {
file f = new file(name, curDir, isDir);
curDir.subfiles.add(f);
}
}

random interviews: k closest neighbors

发表于 2017-04-08 | 分类于 面经题

Given a set of points in a cartesian plane, and a start point , find the k closest points to the starting point.

Points = [(1,2),(2,3),(4,6),(7,9)]
Start Point = (2,2)

Find 2 closest points to start point
这题要考虑的corner case比较多,也是这题的难点。
corner case有:
empty string
string with space
string with positive or negative sign
string with non-digit numbers
overflow integer
对于overflow的处理有两种情况。一个是当前的total乘以10之后超过Integer.MAX_VALUE,由于不能直接比total * 10 > Integer.MAX_VALUE, 我们可以换一种比法。
用Integer.MAX_VALUE / 10 < total 表示判断标准。
但是这又有一种情况就是Integer.MAX_VALUE / 10 是整数除法,可能会有遗漏的情况是最后一位不同。
那么就需要排除Integer.MAX_VALUE / 10 == total && Integer.MAX_VALUE % 10 < digit 的情况。

解法1:Priority Queue, O(NlogK)

最容易想的就是用一个size为k的heap来存储每一个点。如果还没存满k个就直接存入。
如果存满了每当下一个点到p的距离比top的小的时候在把top弹出。
Java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
public List<Point> closestNeighbors(Point[] points, Point center) {
Comparator<Point> comparator = new Comparator<Point>() {
public int compare(Point left, Point right) {
return distance(right, center) - distance(left, center);
}
};
PriorityQueue<Point> queue = new PriorityQueue<Point>(comparator);
for (Point p : points) {
if (queue.size() < k) {
queue.offer(p);
} else {
if (distance(p, center) < queue.peek()) {
queue.poll();
queue.offer(p);
}
}
}
List<Point> res = new ArrayList<Point>();
while (!queue.isEmpty()) {
res.offer(queue.poll());
}
return res;
}
private int distance(Point a, Point b) {
return (a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y);
}

解法2: Quick Select, O(N)

一般面试给出上面的解法就可以了。如果面试官喜欢刁难的话可能是需要这个解法。
思路和find median有点类似,就是先用quick select找出到center距离为第k大的point.然后再扫描一遍数组得到所有小于那个距离的点即可。
code有空的时候再来补上吧。。
Java

lang: java
1

leetcode解题: Largest Rectangle in Histogram (84)

发表于 2017-04-08 | 分类于 刷题总结

Given n non-negative integers representing the histogram’s bar height where the width of each bar is 1, find the area of largest rectangle in the histogram.
alt text

Above is a histogram where width of each bar is 1, given height = [2,1,5,6,2,3].

alt text

The largest rectangle is shown in the shaded area, which has area = 10 unit.

For example,
Given heights = [2,1,5,6,2,3],
return 10.

解法1:Stack O(N)

这题的思路比较巧妙。一般的思路计算面积,办法是先找出左右的边界,然后找出高度。那么这种算法的复杂度是O(N^3)的。
如果我们换一个思路,枚举高度而不是枚举边界。那么对于任意一个高度的bar,我们只需要找出来他左面第一个比它矮的和右边第一个比它矮的bar就能算出来对应的使用这个bar作为最高高度的面积了。
那么这里需要记录左面的已经遍历过的高度。如果说我们维护一个递增的stack,每一个栈顶元素他对应的左面的比他小的bar的位置就确定了。
如果碰到右面比他矮的bar,那么我们就可以计算出当前栈顶的bar对应的面积。
stack中存上index而不是高度方便计算面积
并且要注意计算到最后一个bar之后要清理stack中还存在的bar
Java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
public class Solution {
public int largestRectangleArea(int[] heights) {
if (heights == null || heights.length == 0) {
return 0;
}
Stack<Integer> stack = new Stack<Integer>();
int max = Integer.MIN_VALUE;
stack.push(0);
for (int i = 1; i < heights.length; ++i) {
int current = heights[i];
while (!stack.isEmpty() && current < heights[stack.peek()]) {
int bar = heights[stack.pop()];
int left = stack.isEmpty()? -1 : stack.peek();
max = Math.max(bar * (i - left - 1), max);
}
stack.push(i);
}
while (!stack.isEmpty()) {
int bar = heights[stack.pop()];
while (!stack.isEmpty() && heights[stack.peek()] == bar) {
stack.pop();
}
int left = stack.isEmpty() ? -1 : stack.peek();
max = Math.max(max, bar * (heights.length - left - 1));
}
return max;
}
}

另一种写法较为简单。诀窍是在数组的最后放一个0,这样可以保证清空stack中的值。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public class Solution {
public int largestRectangleArea(int[] heights) {
if (heights == null || heights.length == 0) {
return 0;
}
int res = 0;
Stack<Integer> stack = new Stack<Integer>();
int[] h = Arrays.copyOf(heights, heights.length + 1); // padding zero at the end
for (int i = 0; i < h.length; ++i) {
int bar = h[i];
while (!stack.empty() && bar < h[stack.peek()]) {
int last = h[stack.pop()];
// calculate the width
int width = stack.empty() ? i : i - stack.peek() - 1;
res = Math.max(res, width * last);
}
stack.push(i);
}
return res;
}
}

random interviews: check if a piece is valid in a go game

发表于 2017-04-07 | 分类于 面经题

Given a go board, check if a piece is alive or not.

1
2
3
XXX
X0X
XXX

is not alive

1
2
3
XXX
X0 X
XXXX

is still alive

Assume your piece is marked as 1, enemy’s pieces are marked as -1. Empty space is marked as 0.

解法1:DFS

Java

1
2
3
4
5
6
7
8
9
10
11
12
13
public bool isAlive(int[][] board, int i, int j) {
// Mark visited nodes as Integer.MAX_VALUE;
if (i < 0 || i >= board.length || j < 0 || j >= board[0].length || board[i][j] == -1 || board[i][j] == Integer.MAX_VALUE) {
return false;
}
if (board[i][j] == 0) {
return true;
}
board[i][j] = Integer.MAX_VALUE;
return isAlive(board, i + 1, j) || isAlive(board, i - 1, j) || isAlive(board, i, j + 1) || isAlive(board, i, j - 1);
}

leetcode解题: Most Frequent Subtree Sum (508)

发表于 2017-04-07 | 分类于 刷题总结

Given the root of a tree, you are asked to find the most frequent subtree sum. The subtree sum of a node is defined as the sum of all the node values formed by the subtree rooted at that node (including the node itself). So what is the most frequent subtree sum value? If there is a tie, return all the values with the highest frequency in any order.

Examples 1
Input:

5
/ \
2 -3
return [2, -3, 4], since all the values happen only once, return all of them in any order.
Examples 2
Input:

5
/ \
2 -5
return [2], since 2 happens twice, however -5 only occur once.
Note: You may assume the sum of values in any subtree is in the range of 32-bit signed integer.

解法1:Tree traversal + HashMap O(N)

计算每一个节点的sum很方便,就是leftsum + rightsum。然后用一个hashmap维护每一个sum的出现的频率。
最后统计最大频率的key。下面的解法我用了排序,实际上不需要排序。只需要遍历两遍,一遍找出最大频率,第二部就是找出所有频率为max的key就可以了。
Java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
public class Solution {
public int[] findFrequentTreeSum(TreeNode root) {
if (root == null) {
return new int[0];
}
HashMap<Integer, Integer> map = new HashMap<Integer, Integer>();
helper(root, map);
// Sort map entry based on the frequency
Comparator<Map.Entry<Integer, Integer>> comparator = new Comparator<Map.Entry<Integer, Integer>>() {
public int compare(Map.Entry<Integer, Integer> left, Map.Entry<Integer, Integer> right) {
return right.getValue().compareTo(left.getValue());
}
};
List<Map.Entry<Integer, Integer>> res = new ArrayList<Map.Entry<Integer, Integer>>();
for (Map.Entry<Integer, Integer> entry : map.entrySet()) {
res.add(entry);
}
res.sort(comparator); // Sort by frequency in decreasing order
int maxFreq = res.get(0).getValue();
List<Integer> temp = new ArrayList<Integer>();
for (int i = 0; i < res.size(); ++i) {
if (res.get(i).getValue() == maxFreq) {
temp.add(res.get(i).getKey());
}
}
int[] resArray = new int[temp.size()];
for (int i = 0; i < temp.size(); ++i) {
resArray[i] = temp.get(i);
}
return resArray;
}
private int helper(TreeNode root, Map<Integer, Integer> freqMap) {
if (root == null) {
return 0;
}
int left = helper(root.left, freqMap);
int right = helper(root.right, freqMap);
int sum = left + right + root.val;
freqMap.put(sum, freqMap.getOrDefault(sum, 0) + 1);
return sum;
}
}

leetcode解题: Sliding Window Maximum (239)

发表于 2017-04-07 | 分类于 刷题总结

Given an array nums, there is a sliding window of size k which is moving from the very left of the array to the very right. You can only see the k numbers in the window. Each time the sliding window moves right by one position.

For example,
Given nums = [1,3,-1,-3,5,3,6,7], and k = 3.

1
2
3
4
5
6
7
8
Window position Max
--------------- -----
[1 3 -1] -3 5 3 6 7 3
1 [3 -1 -3] 5 3 6 7 3
1 3 [-1 -3 5] 3 6 7 5
1 3 -1 [-3 5 3] 6 7 5
1 3 -1 -3 [5 3 6] 7 6
1 3 -1 -3 5 [3 6 7] 7

Therefore, return the max sliding window as [3,3,5,5,6,7].

Note:
You may assume k is always valid, ie: 1 ≤ k ≤ input array’s size for non-empty array.

Follow up:
Could you solve it in linear time?

Hint:

How about using a data structure such as deque (double-ended queue)?
The queue size need not be the same as the window’s size.
Remove redundant elements and the queue should store only elements that need to be considered

解法1:Heap

这题用Heap来解的话比较直观,维护一个k大小的priorityqueue。这里有一个用法是可以用Collections.reverseOrder()来生成一个comparator。
但是复杂度感觉不太清楚。remove的复杂度是O(k), insert的复杂度是O(logk),感觉整体的复杂度应该是O(NK),而有些地方说是O(NlogK).  
Java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public class Solution {
public int[] maxSlidingWindow(int[] nums, int k) {
if (nums == null || nums.length == 0) {
return new int[0];
}
PriorityQueue<Integer> queue = new PriorityQueue<Integer>(Collections.reverseOrder());
int[] res = new int[nums.length - k + 1];
for (int i = 0; i < nums.length; ++i) {
if (queue.size() >= k) {
queue.remove(nums[i - k]);
}
queue.offer(nums[i]);
if (i + 1 >= k) {
res[i - k + 1] = queue.peek();
}
}
return res;
}
}

解法2: double linked list (deque), O(N)

基本思路是维护一个deque,这个deque的head就存着当前window中的最大值。
那么要维护这么一个数据结构,就要求我们在每一次insert的时候要把所有小于他的数都弹出去。
同时,要维护窗口,需要加入一个的同时也弹出最左边的元素。由于我们在insert的时候有可能已经把需要弹出的元素弹出了,那么就先用一个if语句来判断是否head是一个需要被弹出的元素。
复杂度的分析是基于,每一个元素只可能被弹出和访问一次。所以是O(N)
Java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public class Solution {
public int[] maxSlidingWindow(int[] nums, int k) {
if (nums.length == 0) {
return new int[0];
}
LinkedList<Integer> deque = new LinkedList<Integer>();
int[] res = new int[nums.length - k + 1];
for (int i = 0; i < nums.length; ++i) {
if (!deque.isEmpty() && deque.peekFirst() == i - k) {
deque.removeFirst();
}
while (!deque.isEmpty() && nums[deque.peekLast()] < nums[i]) {
deque.removeLast();
}
deque.offer(i);
if (i + 1 >= k) {
res[i - k + 1] = nums[deque.peekFirst()];
}
}
return res;
}
}

leetcode解题: Serialize and Deserialize BST (449)

发表于 2017-03-30 | 分类于 刷题总结

Serialization is the process of converting a data structure or object into a sequence of bits so that it can be stored in a file or memory buffer, or transmitted across a network connection link to be reconstructed later in the same or another computer environment.

Design an algorithm to serialize and deserialize a binary search tree. There is no restriction on how your serialization/deserialization algorithm should work. You just need to ensure that a binary search tree can be serialized to a string and this string can be deserialized to the original tree structure.

The encoded string should be as compact as possible.

Note: Do not use class member/global/static variables to store states. Your serialize and deserialize algorithms should be stateless.

解法1:

Java

1

leetcode解题: Rotate Function (396)

发表于 2017-03-30 | 分类于 刷题总结

Given an array of integers A and let n to be its length.

Assume Bk to be an array obtained by rotating the array A k positions clock-wise, we define a “rotation function” F on A as follow:

F(k) = 0 Bk[0] + 1 Bk[1] + … + (n-1) * Bk[n-1].

Calculate the maximum value of F(0), F(1), …, F(n-1).

Note:
n is guaranteed to be less than 105.

Example:

1
2
3
4
5
6
7
8
A = [4, 3, 2, 6]
F(0) = (0 * 4) + (1 * 3) + (2 * 2) + (3 * 6) = 0 + 3 + 4 + 18 = 25
F(1) = (0 * 6) + (1 * 4) + (2 * 3) + (3 * 2) = 0 + 4 + 6 + 6 = 16
F(2) = (0 * 2) + (1 * 6) + (2 * 4) + (3 * 3) = 0 + 6 + 8 + 9 = 23
F(3) = (0 * 3) + (1 * 2) + (2 * 6) + (3 * 4) = 0 + 2 + 12 + 12 = 26
So the maximum value of F(0), F(1), F(2), F(3) is F(3) = 26.

解法1:找规律 O(N) Time + O(1) Space

这题用找规律的办法,找规律的时候把数字简化成A,B,C,D.
f(0) = 0A + 1B + 2C + 3D
f(1) = 0D + 1A + 2B + 3C
f(2) = OC + 1D + 2A + 3B

在考虑一个sum = 1A + 1B + 1C + 1D
那么可以得到
f(1) = f(0) + sum - 4D
f(2) = f(1) + sum - 4C
…
于是一个O(N)的解法就出来了
Java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class Solution {
public int maxRotateFunction(int[] A) {
if (A == null || A.length == 0) {
return 0;
}
int f = 0;
int sum = 0;
for (int i = 0; i < A.length; ++i) {
f += i * A[i];
sum += A[i];
}
int res = f; // f(0)
for (int i = 1; i < A.length; ++i) {
f = f + sum - A.length * A[A.length - i];
res = Math.max(res, f);
}
return res;
}
}

1…232425…46
Bigteemo

Bigteemo

454 日志
4 分类
70 标签
© 2017 Bigteemo
由 Hexo 强力驱动
主题 - NexT.Mist