Posts Tagged ‘easy’
[leetcode] Clone Graph | 克隆无向图
Posted October 8, 2013
on:倒是20分钟写出来了bugfree,比较喜欢这种利用data structure的题,感觉试一试总能想出来。
这个题就是基本BFS,要点是生成新节点的同时,怎么把新节点和其他新节点连起来呢?这就需要一个新旧节点对应map,每次生成新节点A’,要把dequeue的这个parent B对应的新节点B’和当前作为child的新节点A’连起来。注意单向连就行了(B’->A)’,因为下次把A当作root的时候,还会经历B作为child,这时再A’->B’。
public UndirectedGraphNode cloneGraph(UndirectedGraphNode node) { if (node == null) return null; Queue<UndirectedGraphNode> q = new LinkedList<UndirectedGraphNode>(); Map<UndirectedGraphNode, UndirectedGraphNode> map = new HashMap<UndirectedGraphNode, UndirectedGraphNode>(); enqueueAndClone(q, node, map); while (!q.isEmpty()) { UndirectedGraphNode parent = q.poll(); for (UndirectedGraphNode child : parent.neighbors) { if (!map.containsKey(child)) enqueueAndClone(q, child, map); map.get(parent).neighbors.add(map.get(child));//不管是否visit过,都要单向连接 } } return map.get(node); } private void enqueueAndClone(Queue<UndirectedGraphNode> q, UndirectedGraphNode node, Map<UndirectedGraphNode, UndirectedGraphNode> map) { q.add(node); UndirectedGraphNode newNode = new UndirectedGraphNode(node.label); map.put(node, newNode); }
- In: classic | leetcode
- Leave a Comment
经典题,注意balanced的定义:左右子树都balance,且高度差<=1。所以下面这个也是balanced的,即使a的做右子树都不是完全树。
a / \ b d / \ c e
唯一的trick:不用生成新的data structure来保存“boolean isBalanced, int height”,直接用height = -1表示不平衡就行。
public boolean isBalanced(TreeNode root) { return getHeight(root) >= 0; } private int getHeight(TreeNode root) { if (root == null) return 0; int leftHeight = getHeight(root.left); if (leftHeight < 0) return -1; int rightHeight = getHeight(root.right); if (rightHeight < 0) return -1; if (Math.abs(leftHeight - rightHeight) > 1) return -1; return Math.max(leftHeight, rightHeight) + 1; }
- In: 面经
- Leave a Comment
五分钟bug free,忍不住有成就感。
思路:root <= x,说明肯定不在左边,往右找;root >x,有可能是本身:如果root.left没找到,那就是本身了;如果找到了,那就返回找到那个。
public TreeNode getImmediateNext(TreeNode node, int x) { if (node == null) return null; if (node.val <= x) { return getImmediateNext(node.right, x); } else { TreeNode parent = node; TreeNode findAtLeft = getImmediateNext(node.left, x); return findAtLeft== null ? parent : findAtLeft; } }
[leetcode] restore ip address | 把一个string parse成valid ip地址,返回所有valid parse
Posted August 11, 2013
on:和电话号码一样,基本的DFS。mark一下,下次再准备面试的时候可能就忘了这种题型了。
public ArrayList<String> restoreIpAddresses(String s) { ArrayList<String> result = new ArrayList<String>(); String[] curr = new String[4]; restore(s, 0, curr, result); return result; } private void restore(String s, int level, String[] curr, ArrayList<String> result) { if (level == 4) { if (s.isEmpty()) { result.add(convertToIpString(curr)); } return; } else if (s.isEmpty()) return; for (int i = 1; i <= 3 && i <= s.length(); i++) { String left = s.substring(0, i); String right = s.substring(i); if (validIp(left)) { curr[level] = left; restore(right, level+ 1, curr, result); } } } private boolean validIp(String s) { if (s.length() > 1 && s.charAt(0) == '0') return false; return Integer.valueOf(s) < 256; } private String convertToIpString(String[] curr) { StringBuilder sb = new StringBuilder(); for (String s : curr) { sb.append(s); sb.append("."); } sb.deleteCharAt(sb.length() - 1); return sb.toString(); }
[leetcode] Populating Next Right Pointers in Each Node II | 把二叉树横向next节点populate了
Posted August 9, 2013
on:很简单的题,因为熟悉了用两个list做tree的bfs,所以这里一层一层iterate就行了,上一层反正已经做完了,所以能直接横着遍历上一层,把下一层populate了。轻松过。
本来觉得是弱智题,但是基本从来不top down的做树的题,写完还真挂在bug上了。
top down利用leaf的树题一般是这样的pattern:
void topDown(Node node) { if (node == null) //this means reaching a branch that only one side has something, the other side is this (null) if (node.left == null && root.right == null) //this is leaf, do something, then return; topDown(node.left); topDown(node.right); }
和平时做的preorder(中左右)的区别:preOrder这种遍历下来,的确会在empty node的时候停,但是不能判断什么时候到了叶子节点。而topDown利用了叶子节点的定义来判断当前节点是否叶子,可以这时候做一些运算。
void preOrder(Node node) { if (node == null) //this could either mean parent is a leaf, or parent's this branch is empty but has another child } preOrder(node.left); preOrder(node.right); }
[leetcode] N-Queens | 8皇后问题
Posted August 2, 2013
on:这题做了好几遍了,(尽管每次都有进步)但是因为一直用的二维数组char[][] board,到leetcode上跑才发现超时。问题出现在算“对角能不能放”的时候,因为char[][]要遍历才能知道之前都在哪些位置放了皇后,所以多花了遍历的时间。书上的算法是用int[] queenColAtRow,这样queenColAtRow[i]就表示“在第i行,把queen放在了result位置上“。这样可以直接O(1)的知道每行queen都放在哪列了,少遍历一维,大的就过了。
public int totalNQueens(int n) { ArrayList<String[]> solveNQueens = solveNQueens(n); return solveNQueens.size(); } public ArrayList<String[]> solveNQueens(int n) { //生成全是.的board,因为要返回board本身,所以现在先填好了。 char[][] board = new char[n][n]; for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { board[i][j] = '.'; } } ArrayList<String[]> result = new ArrayList<String[]>(); placeQueen(board, 0, n, result); return result; } private void placeQueen(char[][] board, int row, int n, ArrayList<String[]> result) { if (row == n) { result.add(copyBoard(board)); return; } for (int col = 0; col < n; col++) { if (canPlace(board, row, col)) { board[row][col] = 'Q'; placeQueen(board, row + 1, n, result); board[row][col] = '.'; } } } private boolean canPlace(char[][] board, int row, int col) { // row is definitely fine for (int i = 0; i <= row; i++) { if (board[i][col] == 'Q') return false; } for (int i = 0; i < row; i++) { for (int j = 0; j < board.length; j++) { if (board[i][j] == 'Q' && Math.abs(i - row) == Math.abs(j - col)) return false; } } return true; }
- In: leetcode
- 3 Comments
尼玛这破题居然跑了好几遍才对!
一开始错的方法:
public int minDepth(TreeNode root) { if (root == null) return 0; int left = minDepth(root.left); int right = minDepth(root.right); return Math.min(left, right) + 1; }
比如a#b这种左子树为空的树,我直接认为左子树的depth为0了,那当然左子树的depth小,然后parent直接取了0+1。问题在于,某个子树是null的时候,它不是叶子节点啊!这个时候就算没形成一个叶子到root的path,则认为depth为正无穷。改进:
public int minDepth(TreeNode root) { if (root == null) return Intger.MAX_VALUE; if (root.left == null && root.right == null) return 1; //说明是个leaf了! int left = minDepth(root.left); int right = minDepth(root.right); return Math.min(left, right) + 1; }
忍不住回忆为啥做maxdepth的时候就没遇见问题呢?(如下)因为求的是max,所以那种某个子树为0的情况就被Math.max给解决了。总之这种题最好做完了试一试,一试就能立刻看出毛病了,自己干想还真想不到。
public int maxDepth(TreeNode root) { if (root == null) return 0; int left = maxDepth(root.left); int right = maxDepth(root.right); return Math.max(left, right) + 1; }