国美供应链部门面试笔试题两道
1: 判断链表是否有环
public class AppTest { public static void main(String[] args) { } public boolean hasCircle(ListNode header) { ListNode p1 = header; ListNode p2 = header; while (true) { // 无环p2先到达终点 if (p2 == null || p2.next == null) { return false; } p2 = p2.next.next; p1 = p1.next; // 有环p2追上p1了 if (p1 == p2) { return true; } } } } class ListNode { public ListNode next; public ListNode() { } }
需要说明算法复杂度,即要证明p2和p1 一定会在某个节点相遇且相遇时p1走了多少步。
2:使用非递归实现二叉树的前序遍历
public class Main { public static void main(String[] args) { Node[] result = null ; Node node = new Node(1); node.left = new Node(2); node.right = new Node(3); node.left.left = new Node(4); node.left.right = new Node(5); node.right.left = new Node(6); node.right.right = new Node(7); result = pre(node) ; print(result); } public static Node[] pre(Node root) { if (root == null) { return new Node[]{}; } List<Node> nodeList = new ArrayList<>() ; Stack<Node> nodeStack = new Stack<>() ; nodeStack.push(root) ; while (!nodeStack.empty()) { Node curItem = nodeStack.peek(); // 没有左子树或者左子树已经被访问了 则当前节点出栈 if (curItem.left == null || curItem.visited ==1){ nodeStack.pop(); curItem.visited = 1; nodeList.add(curItem); Node right = curItem.right ; if(right != null){ // 右孩子不为空 nodeStack.push(right); }else { // 右孩子为空 则需要标记父节点的左子树已经被访问 if (!nodeStack.empty()) { curItem = nodeStack.peek(); curItem.visited = 1; } } } // 左子树没有被访问 如果左孩子不为空则压栈 while (curItem.visited == 0) { Node item = curItem.left ; if(item != null) { nodeStack.push(item); curItem = item ; }else { break; } } } int size = nodeList.size(); Node[] result = new Node[size]; nodeList.toArray(result); return result; } public static void print(Node[] result){ for(Node node:result){ System.out.println(node.val); } } } class Node { public int visited = 0 ; // 标识左子树是否被访问 public int val ; public Node(int val) { this.val = val; } public int getVal() { return val; } public Node left; public Node right; }