算法|二叉树剑指offer

2022-12-24  本文已影响0人  激扬飞雪

一、 剑指 Offer II 047. 二叉树剪枝

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    private boolean isZero(TreeNode root) {
        if (root == null) return true;
        if (root.val != 0) return false;
        if (!isZero(root.left)) return false;
        return isZero(root.right);
    }
    public TreeNode pruneTree(TreeNode root) {
        if (root == null) return null;
        if (isZero(root)) return null;
        root.left = pruneTree(root.left);
        root.right = pruneTree(root.right);
        return root;
    }
}

二、 剑指 Offer II 048. 序列化与反序列化二叉树

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
public class Codec {

    // Encodes a tree to a single string.
    public String serialize(TreeNode root) {
        StringBuilder str = new StringBuilder();
        if (root == null) {
            str.append("[]");
            return str.toString();
        }
        str.append("[");
        Queue<TreeNode> queue = new LinkedList<>();
        queue.offer(root);
        while (!queue.isEmpty()){
            int size = queue.size();
            while (size -- > 0) {
                TreeNode treeNode = queue.poll();
                if (treeNode == null) {
                    str.append("null,");
                    continue;
                }
                str.append(treeNode.val + ",");
                queue.offer(treeNode.left);
                queue.offer(treeNode.right);
            }
        }
        str.deleteCharAt(str.length() - 1);
        str.append("]");
        // System.out.println(str.toString());
        return str.toString();
    }

    // Decodes your encoded data to tree.
    public TreeNode deserialize(String data) {
        StringBuilder str = new StringBuilder(data);
        str.deleteCharAt(0);
        str.deleteCharAt(str.length() - 1);
        System.out.println(str.toString());
        if (str.isEmpty()) return null;
        String[] els = str.toString().split(",");
        for (int i = 0; i < els.length; i++){
            System.out.println(els[i]);
        }
        int index = 0;
        Queue<TreeNode> queue = new LinkedList<>();
        TreeNode root = new TreeNode();
        root.val = Integer.parseInt(els[index++]);
        queue.offer(root);
        while (!queue.isEmpty()) {
            int size = queue.size();
            while (size-- > 0) {
                TreeNode treeNode = queue.poll();
                if ("null".equals(els[index])) {
                    index++;
                } else {
                    TreeNode leftNode = new TreeNode();
                    leftNode.val = Integer.parseInt(els[index++]);
                    treeNode.left = leftNode;
                    queue.offer(leftNode);
                }

                if ("null".equals(els[index])) {
                    index++;
                } else {
                    TreeNode rightNode = new TreeNode();
                    rightNode.val = Integer.parseInt(els[index++]);
                    treeNode.right = rightNode;
                    queue.offer(rightNode);
                }
                
            }
        }
        return root;
    }
}

// Your Codec object will be instantiated and called as such:
// Codec ser = new Codec();
// Codec deser = new Codec();
// TreeNode ans = deser.deserialize(ser.serialize(root));

剑指 Offer II 077. 链表排序

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode sortList(ListNode head) {
        if (head == null || head.next == null) return head;
        ListNode fast = head;
        ListNode slow = head;
        ListNode pre = null;
        while (fast != null && fast.next != null){
            pre = slow;
            fast = fast.next.next;
            slow = slow.next;
        }
        if (pre != null) pre.next = null;
        ListNode l1 = sortList(head);
        ListNode l2 = sortList(slow);
        return merger(l1, l2);
    }

    private ListNode merger(ListNode l1, ListNode l2){
        ListNode dummy = new ListNode();
        ListNode cur = dummy;
        while (l1 != null && l2 != null){
            if (l1.val > l2.val) {
                cur.next = l2;
                l2 = l2.next;
            } else {
                cur.next = l1;
                l1 = l1.next;
            }
            cur = cur.next;
        }
        if (l1 != null) {
            cur.next = l1;
        }
        if (l2 != null) {
            cur.next = l2;
        }

        return dummy.next;
    }
}

剑指 Offer II 078. 合并排序链表

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    private ListNode merger(ListNode l1, ListNode l2) {
        ListNode dummy = new ListNode(-1);
        ListNode cur = dummy;
        while (l1 != null && l2 != null){
            if (l1.val > l2.val) {
                cur.next = l2;
                l2 = l2.next;
            } else {
                cur.next = l1;
                l1 = l1.next;
            }
            cur = cur.next;
        }
        cur.next = l1 != null ? l1 : l2;
        return dummy.next;
    }
    private ListNode sortList(ListNode[] lists, int left, int right) {
        if (left >= right) return lists[right];
        int mid = left + (right - left) / 2;
        ListNode l1 = sortList(lists, left, mid);
        ListNode l2 = sortList(lists, mid + 1, right);
        return merger(l1, l2);
    }

    public ListNode mergeKLists(ListNode[] lists) {
        if (lists == null || lists.length == 0) return null; 
        return sortList(lists, 0, lists.length - 1);
    }

}

83. 删除排序链表中的重复元素

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode deleteDuplicates(ListNode head) {
        if (head == null) return head;
        ListNode fast = head.next;
        ListNode slow = head;
        while (fast != null) {
            System.out.println(fast.val + " " + slow.val);
            if (slow.val != fast.val) {
                slow.next = fast;
                slow = fast;
            }
            fast = fast.next;
        }
        slow.next = null;
        return head;
    }
}

82. 删除排序链表中的重复元素 II

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode deleteDuplicates(ListNode head) {
        if (head == null || head.next == null) return head;
        ListNode dummy = new ListNode(-1);
        dummy.next = head;
        ListNode cur = head;
        ListNode pre = dummy;
        while (cur != null && cur.next != null) {
            if (cur.val == cur.next.val) {
                while (cur.next != null && cur.val == cur.next.val) {
                    cur = cur.next;
                }
                pre.next = cur.next;
                cur = cur.next;
            } else {
                pre = cur;
                cur = cur.next;
            }
        }
        return dummy.next;
    }
}

147. 对链表进行插入排序

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode insertionSortList(ListNode head) {
        if (head == null || head.next == null) return head;
        ListNode dummy = new ListNode(-1);
        dummy.next = head;
        ListNode preNode = head;
        ListNode  cur = head.next;
        while (cur != null) {
            //不用交换
            if (cur.val >= preNode.val) {
                preNode = preNode.next;
                cur = cur.next;
                continue;
            }
            //找到插入点
            ListNode tempPre = dummy;
            while (tempPre.next != null) {
                if (tempPre.next.val > cur.val) break;
                tempPre = tempPre.next;
            }
            //删除cur节点
            preNode.next = cur.next;
            //添加节点
            cur.next = tempPre.next;
            tempPre.next = cur;
            cur = preNode.next;
        }
        return dummy.next;
    }
}

25. K 个一组翻转链表

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    
    public ListNode reverseKGroup(ListNode head, int k) {
        if (head == null || head.next == null) return head;
        ListNode dummy = new ListNode();
        dummy.next = head;
        ListNode cur = head;
        ListNode pre = dummy;
        while (cur != null) {
            int n = k - 1;
            ListNode temp = cur.next;
            while (n-- > 0) {
                if (temp == null) return dummy.next;
                temp = temp.next;
            }
            ListNode next = temp;
            n = k;
            //翻转
            ListNode preNode = null;
            ListNode curNode = cur;
            while (n-- > 0){
                ListNode nextNode = curNode.next;
                curNode.next = preNode;
                preNode = curNode;
                curNode = nextNode;
            }
            cur.next = next;
            pre.next = preNode;
            pre = cur;
            cur = next;
        }
        return dummy.next;
    }
}

61. 旋转链表

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode rotateRight(ListNode head, int k) {
        if (k == 0 || head == null || head.next == null) return head;
        int n = 1;
        ListNode cur = head;
        while (cur.next != null) {
            n++;
            cur = cur.next;
        }
    
        ListNode tail = cur;
        int index = k % n;
        if (index == 0) return head;
        cur = head;
        int b = n - index - 1;
        while (b-- > 0) {
            cur = cur.next;
        }
    
        ListNode newHead = cur.next;
        cur.next = null;
        tail.next = head;
        return newHead;
    }
}

86. 分隔链表

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode partition(ListNode head, int x) {
        if (head == null || head.next == null) return head;
        ListNode cur = head;
        ListNode smallDummy = new ListNode(-1);
        ListNode bigDummy = new ListNode(-1);
        ListNode smallCur = smallDummy;
        ListNode bigCur = bigDummy;
        while (cur != null) {
            if (cur.val >= x) {
                bigCur.next = cur;
                bigCur = bigCur.next;
            } else {
                smallCur.next = cur;
                smallCur = smallCur.next;
            }
            cur = cur.next;
        }
        bigCur.next = null;
        smallCur.next = bigDummy.next;
        return smallDummy.next;
    }
}

328. 奇偶链表

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode oddEvenList(ListNode head) {
        if (head == null || head.next == null) return head;
        ListNode evenDummy = new ListNode(-1);
        ListNode oddDummy= new ListNode(-1);
        ListNode evenCur = evenDummy;
        ListNode oddCur = oddDummy;
        ListNode cur = head;
        int n = 1;
        while (cur != null){
            if (n % 2 == 0) {
                //偶数
                oddCur.next = cur;
                oddCur = oddCur.next;
            } else {
                //奇数
                evenCur.next = cur;
                evenCur = evenCur.next;
            }
            n++;
            cur = cur.next;
        }
        evenCur.next = oddDummy.next;
        oddCur.next = null;
        return evenDummy.next;
    }
}
/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode oddEvenList(ListNode head) {
        if (head == null || head.next == null) return head;
        //偶数  
        ListNode evenHead = head.next;
        //奇数
        ListNode odd = head;
        ListNode even = evenHead;
        while (even != null && even.next != null) {
            odd.next = even.next;
            odd = odd.next;
            even.next = odd.next;
            even = even.next;
        }
        odd.next = evenHead;
        return head;
    }
}

2. 两数相加

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        ListNode cur1 = l1;
        ListNode cur2 = l2;
        int flag = 0;
        ListNode dummy = new ListNode(-1);
        ListNode cur = dummy;
        while (cur1 != null || cur2 != null) {
            int val1 = cur1 != null ? cur1.val : 0;
            int val2 = cur2 != null ? cur2.val : 0;
            int sum = val1 + val2 + flag;
            flag = sum / 10;
            sum = sum % 10;
            cur.next = new ListNode(sum);
            cur = cur.next;
            cur1 = cur1 != null ? cur1.next : null;
            cur2 = cur2 != null ? cur2.next : null;
        }
        if (flag == 1) {
            cur.next = new ListNode(1);
        }
        return dummy.next;
    }
}

445. 两数相加 II

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
       if (l1 == null) return l2;
       if (l2 == null) return l1;
       Stack<ListNode> stack1 = new Stack<>();
       ListNode cur1 = l1;
       while (cur1 != null) {
           stack1.push(cur1);
           cur1 = cur1.next;
       }
       Stack<ListNode> stack2 = new Stack<>();
       ListNode cur2 = l2;
       while (cur2 != null) {
           stack2.push(cur2);
           cur2 = cur2.next;     
       }
       int flag = 0;
       ListNode head = null;
       while (!stack1.isEmpty() || !stack2.isEmpty()) {
           int val1 = stack1.isEmpty() ? 0 : stack1.pop().val;
           int val2 = stack2.isEmpty() ? 0 : stack2.pop().val;
           int sum = val1 + val2 + flag;
           flag = sum / 10;
           sum = sum % 10;
           ListNode newNode = new ListNode(sum);
           if (head == null) {
               head = newNode;
           } else {
               newNode.next = head;
               head = newNode;
           }
       }
       if (flag == 1) {
           ListNode newNode = new ListNode(1);
           newNode.next = head;
           head = newNode;
       }
       return head;
    }
}

234. 回文链表

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public boolean isPalindrome(ListNode head) {
        if (head == null || head.next == null) return true;
        ListNode fast = head;
        ListNode slow = head;
        while (fast != null && fast.next != null) {
            fast = fast.next.next;
            slow = slow.next;
        }
        if (fast != null) slow = slow.next;
        //反转
        ListNode cur = slow;
        ListNode pre = null;
        while (cur != null) {
            ListNode next = cur.next;
            cur.next = pre;
            pre = cur;
            cur = next;
        }
        //比较
        cur = pre;
        while (cur != null) {
            if (head.val != cur.val) return false;
            head = head.next;
            cur = cur.next;
        }
        return true;
    }
}
/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    private ListNode reverList(ListNode head) {
        if (head == null || head.next == null) return head;
        ListNode newHead = reverList(head.next);
        head.next.next = head;
        head.next = null;
        return newHead;
    }
    public boolean isPalindrome(ListNode head) {
        if (head == null || head.next == null) return true;
        ListNode fast = head;
        ListNode slow = head;
        while (fast != null && fast.next != null) {
            fast = fast.next.next;
            slow = slow.next;
        }
        if (fast != null) slow = slow.next;
        slow = reverList(slow);
        while (slow != null) {
            if (slow.val != head.val) return false;
            slow = slow.next;
            head = head.next;
        }
        return true;
    }
}

148. 排序链表

归并排序

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    private ListNode meger(ListNode l1, ListNode l2) {
        ListNode dummy = new ListNode(-1);
        ListNode cur = dummy;
        while (l1 != null && l2 != null) {
            if (l1.val > l2.val) {
                cur.next = l2;
                l2 = l2.next;
            } else {
                cur.next = l1;
                l1 = l1.next;
            }
            cur = cur.next;
        }
        cur.next = l1 == null ? l2 : l1;
        return dummy.next;
    }
    public ListNode sortList(ListNode head) {
        if (head == null || head.next == null) return head;
        ListNode fast = head;
        ListNode slow = head;
        ListNode pre = null;
        while (fast != null && fast.next != null) {
            pre = slow;
            fast = fast.next.next;
            slow = slow.next;
        }
        if (pre != null) pre.next = null;
        ListNode l1 = sortList(head);
        ListNode l2 = sortList(slow);
        return meger(l1, l2);
    }
}

//插入排序

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode sortList(ListNode head) {
        if (head == null || head.next == null) return head;
        ListNode cur = head.next;
        ListNode pre = head;
        ListNode dummy = new ListNode(-1);
        dummy.next = head;
        while (cur != null) {
            if (cur.val > pre.val) {
                pre = pre.next;
                cur = cur.next;
                continue;
            }
            ListNode temp = dummy;
            while (temp.next != null) {
                if (temp.next.val > cur.val) break;
                temp = temp.next;
            }
            pre.next = cur.next;
            cur.next = temp.next;
            temp.next = cur;
            cur = pre.next;
        }
        return dummy.next;
    }
}

剑指 Offer II 037. 小行星碰撞

class Solution {
    public int[] asteroidCollision(int[] asteroids) {
        Stack<Integer> stack = new Stack<>();
        for (int i = 0; i < asteroids.length; i++){
            int val = asteroids[i];
            //自己是否毁了
            boolean flag = true;
            //发生碰撞
            while (val < 0 && !stack.isEmpty() && stack.peek() > 0){
                if (stack.peek() < Math.abs(val)) {
                    //栈顶的毁掉
                    stack.pop();
                } else if (stack.peek() == Math.abs(val)){
                    //栈顶毁掉
                    stack.pop();
                    //自己也毁掉
                    flag = false;
                    break;
                } else {
                    //自己毁掉
                    flag = false;
                    break;
                }
            }
            if (flag) {
                stack.push(asteroids[i]);   
            }
        }
        int[] result = new int[stack.size()];
        int index = result.length - 1;
        while (!stack.isEmpty()){
            result[index--] = stack.pop();
        }
        return result;
    }
}

剑指 Offer II 038. 每日温度

class Solution {
    public int[] dailyTemperatures(int[] temperatures) {
        int[] result = new int[temperatures.length];
        Stack<Integer> stack = new Stack<>();
        for (int i = 0; i < temperatures.length; i++){
            while (!stack.isEmpty() && temperatures[stack.peek()] < temperatures[i]){
                result[stack.peek()] = i - stack.peek();
                stack.pop();
            }
            stack.push(i);
        }
        return result;
    }
}

剑指 Offer II 014. 字符串中的变位词

class Solution {
    public boolean checkInclusion(String s1, String s2) {
        if (s1.length() > s2.length()) return false;
        int[] a = new int[26];
        int[] b = new int[26];
        for (int i = 0; i < s1.length(); i++){
            a[s1.charAt(i) - 'a']++;
            b[s2.charAt(i) - 'a']++;
        }
        if (Arrays.equals(a, b)) {
            return true;
        }
        int left = 0;
        int right = s1.length();
        while (right < s2.length()) {
            b[s2.charAt(right) - 'a']++;
            b[s2.charAt(left) - 'a']--;
            if (Arrays.equals(a, b)) return true;
            left++;
            right++;
        }

        return false;
    }
}

剑指 Offer II 018. 有效的回文

class Solution {
    private boolean isNumOrLetter(char c){
        if ((c >= 'a' && c <= 'z') 
        || (c >= 'A' && c <= 'Z') 
        || (c >= '0' && c <= '9')) return true;
        return false;
    }
    public boolean isPalindrome(String s) {
        char[] chs = s.toUpperCase().toCharArray();
        int left = 0;
        int right = chs.length - 1;
        while (left < right) {
            if (!isNumOrLetter(chs[left])) {
                left++;
                continue;
            }
            if (!isNumOrLetter(chs[right])) {
                right--;
                continue;
            }
            System.out.println(chs[left] + " " + chs[right]);
            if (chs[left] != chs[right]) return false;
            left++;
            right--;
        }
        return true;
    }
}

剑指 Offer II 019. 最多删除一个字符得到回文

class Solution {
    private boolean isVail(String s, int left, int right){
        while (left < right){
            if (s.charAt(left) != s.charAt(right)){
                return false;
            }
            left++;
            right--;
        }
        return true;
    }
    public boolean validPalindrome(String s) {
        int left = 0;
        int right = s.length() - 1;
        while (left < right) {
            if (s.charAt(left) == s.charAt(right)) {
                left++;
                right--;
            } else {
                return isVail(s, left + 1, right) || isVail(s, left, right - 1);
            }
        }
        return true;
    }
}

剑指 Offer II 059. 数据流的第 K 大数值

class KthLargest {
    private PriorityQueue<Integer> priorityQueue;
    private int k;
    public KthLargest(int k, int[] nums) {
        priorityQueue = new PriorityQueue<>();
        this.k = k;
        for (int i = 0; i < nums.length; i++){
            priorityQueue.offer(nums[i]);
            if (priorityQueue.size() > k) {
                priorityQueue.poll();
            }
        }
    }
    
    public int add(int val) {
        priorityQueue.offer(val);
        if (priorityQueue.size() > k) {
            priorityQueue.poll();
        }
        return priorityQueue.peek();
    }
}

/**
 * Your KthLargest object will be instantiated and called as such:
 * KthLargest obj = new KthLargest(k, nums);
 * int param_1 = obj.add(val);
 */

剑指 Offer II 085. 生成匹配的括号

class Solution {
    private List<Integer> paths;
    private List<List<Integer>> result;
    private void backTracking(int[] nums, boolean[] uses) {
        if (paths.size() == nums.length) {
            result.add(new ArrayList<>(paths));
            return;
        }
        for (int i = 0; i < nums.length; i++){
            if (uses[i]) continue;
            if (i > 0 && nums[i] == nums[i - 1] && !uses[i - 1]) continue;
            uses[i] = true;
            paths.add(nums[i]);
            backTracking(nums, uses);
            paths.remove(paths.size() - 1);
            uses[i] = false;
        }
    }
    public List<List<Integer>> permuteUnique(int[] nums) {
        paths = new ArrayList<>();
        result = new ArrayList<>();
        boolean[] uses = new boolean[nums.length];
        Arrays.sort(nums);
        Arrays.fill(uses, false);
        backTracking(nums, uses);
        return result;
    }
}

剑指 Offer II 085. 生成匹配的括号

class Solution {
    private List<String> result;
    private void generateParenthesis(int n, String str, int open, int close) {
        if (open > n) return;
        if (close > open) return;
        if (str.length() == n * 2) {
            result.add(str);
            return;
        }
        generateParenthesis(n, str + "(", open + 1, close);
        generateParenthesis(n, str + ")", open, close + 1);
    }
    public List<String> generateParenthesis(int n) {
        result = new ArrayList<>();
        generateParenthesis(n, new String(), 0, 0);
        return result;
    }
}

剑指 Offer II 087. 复原 IP

class Solution {
    private List<String> paths;
    private List<String> result;
    private boolean isVail(String str){
        if (str.length() == 1) return true;
        if (str.length() > 3) return false;
        if (str.charAt(0) == '0') return false;
        if (Integer.parseInt(str) > 255) return false;
        return true;
    }
    private void backTracking(String s, int indexStart){
        if (paths.size() > 4) return;
        if (indexStart == s.length() && paths.size() == 4) {
            StringBuilder stringBuilder = new StringBuilder();
            for (int i = 0; i < paths.size(); i++){
                stringBuilder.append(paths.get(i));
                if (i != paths.size() - 1) {
                    stringBuilder.append(".");
                }
            }
            result.add(stringBuilder.toString());
            return;
        }

        for (int i = indexStart; i < s.length(); i++){
            String str = s.substring(indexStart, i + 1);
            if (!isVail(str)) break;
            paths.add(str);
            backTracking(s, i + 1);
            paths.remove(paths.size() - 1);
        }
    }
    public List<String> restoreIpAddresses(String s) {
        paths = new ArrayList<>();
        result = new ArrayList<>();
        backTracking(s, 0);
        return result;
    }
}

剑指 Offer 36. 二叉搜索树与双向链表

/*
// Definition for a Node.
class Node {
    public int val;
    public Node left;
    public Node right;

    public Node() {}

    public Node(int _val) {
        val = _val;
    }

    public Node(int _val,Node _left,Node _right) {
        val = _val;
        left = _left;
        right = _right;
    }
};
*/
class Solution {
    private Node dummy;
    private Node pre;
    private void tree(Node root) {
        if (root == null) return;
        tree(root.left);
        pre.right = root;
        root.left = pre;
        pre = root;
        tree(root.right);
    }
    public Node treeToDoublyList(Node root) {
        if (root == null) return root;
        dummy = new Node(-1);
        pre = dummy;
        tree(root);
        pre.right = dummy.right;
        dummy.right.left = pre;
        return dummy.right;
    }
}

面试题 02.01. 移除重复节点

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public ListNode removeDuplicateNodes(ListNode head) {
        HashSet<Integer> hashSet = new HashSet<>();
        ListNode dummy = new ListNode(-1);
        dummy.next = head;
        ListNode pre = dummy;
        while (pre.next != null) {
            if (hashSet.contains(pre.next.val)) {
                pre.next = pre.next.next;
            } else {
                hashSet.add(pre.next.val);
                pre = pre.next;
            }
        }
        return dummy.next;
    }
}

面试题 02.04. 分割链表

//使用两个虚拟头结点

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public ListNode partition(ListNode head, int x) {
        ListNode smallDummy = new ListNode(-1);
        ListNode bigDummy = new ListNode(-1);
        ListNode smallCur = smallDummy;
        ListNode bigCur = bigDummy;
        ListNode cur = head;
        while (cur != null) {
            if (cur.val < x) {
                smallCur.next = cur;
                smallCur = smallCur.next;
            } else {
                bigCur.next = cur;
                bigCur = bigCur.next;
            }
            cur = cur.next;
        }
        smallCur.next = bigDummy.next;
        bigCur.next = null;
        return smallDummy.next;
    }
}

//快排思想

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public ListNode partition(ListNode head, int x) {
        if (head == null) return head;
        ListNode right = head;
        ListNode left = head;
        while (right != null) {
            if (right.val < x) {
                //交换
                int temp = left.val;
                left.val = right.val;
                right.val = temp;
                left = left.next;
            }
            right = right.next;
        }
        return head;
    }
}

面试题 02.05. 链表求和

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        ListNode cur1 = l1;
        ListNode cur2 = l2;
        int flag = 0;
        ListNode dummy = new ListNode(-1);
        ListNode cur = dummy;
        while (cur1 != null || cur2 != null){
            int val1 = cur1 != null ? cur1.val : 0;
            int val2 = cur2 != null ? cur2.val : 0;
            int sum = val1 + val2 + flag;
            flag = sum / 10;
            sum = sum % 10;
            ListNode newNode = new ListNode(sum);
            cur.next = newNode;
            cur = newNode;
            cur1 =  cur1 == null ? null : cur1.next;
            cur2 = cur2 == null ? null : cur2.next;
        }
        if (flag == 1) {
            cur.next = new ListNode(1);
        }
        return dummy.next;
    }
}

面试题 02.06. 回文链表

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public boolean isPalindrome(ListNode head) {
        ListNode fast = head;
        ListNode slow = head;
        while (fast != null && fast.next != null) {
            fast = fast.next.next;
            slow = slow.next;
        }
        if (fast != null) slow = slow.next;
        //翻转后半部分
        ListNode cur = slow;
        ListNode pre = null;
        while (cur != null){
            ListNode next = cur.next;
            cur.next = pre;
            pre = cur;
            cur = next;
        }
        cur = pre;
        while (cur != null) {
            if (cur.val != head.val) return false;
            head = head.next;
            cur = cur.next;
        }
        return true;
    }
}

//放入list中 双指针判断回文串

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public boolean isPalindrome(ListNode head) {
        ListNode cur = head;
        List<Integer> list = new ArrayList<>();
        while (cur != null) {
            list.add(cur.val);
            cur = cur.next;
        }
        int left = 0;
        int right = list.size() - 1;
        while (left < right) {
            
            if (!list.get(left).equals(list.get(right))) return false;
            left++;
            right--;
        }
        return true;
        
    }
}

面试题 03.03. 堆盘子

class StackOfPlates {
    private int cap;
    private List<Stack<Integer>> list;
    public StackOfPlates(int cap) {
        this.cap = cap;
        list = new ArrayList<>();
    }
    
    public void push(int val) {
        if (cap <= 0) return;
        //空或者最后一个满了 添加一个新的元素
        if (list.isEmpty() || list.get(list.size() - 1).size() >= cap) {
            Stack<Integer> stack = new Stack<>();
            list.add(stack);
        }
        list.get(list.size() - 1).push(val);
    }
    
    public int pop() {
        return popAt(list.size() - 1);
    }
    
    public int popAt(int index) {
        if (index < 0 || index >= list.size()) return -1;
         Stack<Integer> stack = list.get(index);
         if (stack.isEmpty()) return - 1;
         int result = stack.pop();
         if (stack.isEmpty()) {
             list.remove(index);
         }
         return result;
    }
}

/**
 * Your StackOfPlates object will be instantiated and called as such:
 * StackOfPlates obj = new StackOfPlates(cap);
 * obj.push(val);
 * int param_2 = obj.pop();
 * int param_3 = obj.popAt(index);
 */

面试题 04.03. 特定深度节点链表

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public ListNode[] listOfDepth(TreeNode tree) {
        if (tree == null) return null;
        List<ListNode> list = new ArrayList<>();
        Queue<TreeNode> queue = new LinkedList<>();
        queue.offer(tree);
        while (!queue.isEmpty()){
            int size = queue.size();
            ListNode dummy = new ListNode();
            ListNode cur = dummy;
            while (size-- > 0) {
                TreeNode treeNode = queue.poll();
                cur.next = new ListNode(treeNode.val);
                cur = cur.next;
                if (treeNode.left != null) queue.offer(treeNode.left);
                if (treeNode.right != null) queue.offer(treeNode.right);
            }
            list.add(dummy.next);
        }
        ListNode[] result = new ListNode[list.size()];
        for (int i = 0; i < result.length; i++){
            result[i] = list.get(i);
        }
        return result;
    }
}

面试题 16.25. LRU 缓存

class LRUCache {
    static class ListNode {
        int val;
        int key;
        ListNode next;
        ListNode pre;
        ListNode(){

        }
        ListNode(int key, int val){
            this.key = key;
            this.val = val;
        }
    }
    private ListNode head;
    private ListNode tail;
    private int capacity;
    private HashMap<Integer, ListNode> hashMap;
    public LRUCache(int capacity) {
        head = new ListNode();
        tail = new ListNode();
        head.next = tail;
        tail.pre = head;
        this.capacity = capacity;
        hashMap = new HashMap<>();
    }


    private void moveListNodeToHead(ListNode listNode){
        //删除listNode
       
        ListNode preNode = listNode.pre;
        ListNode next = listNode.next;
        preNode.next = next;
        next.pre = preNode;
        listNode.pre = null;
        listNode.next = null;
        //添加到头部
        addListNodeToHead(listNode);
    }

    private void addListNodeToHead(ListNode listNode){
        //添加到头部
        ListNode nextNode = head.next;
        head.next = listNode;
        listNode.pre = head;
        listNode.next = nextNode;
        nextNode.pre = listNode;
    }
    
    public int get(int key) {
        if (!hashMap.containsKey(key)) return -1;
        ListNode listNode = hashMap.get(key); 
        moveListNodeToHead(listNode);
        return listNode.val;
    }
    
    private ListNode removeLast(){
        ListNode preNode = tail.pre;
        ListNode prePreNode = preNode.pre;
        prePreNode.next = tail;
        tail.pre = prePreNode;
        preNode.pre = null;
        preNode.next = null;
        return preNode;
    }
    public void put(int key, int value) {
        if (hashMap.containsKey(key)) {
            ListNode listNode = hashMap.get(key);
            listNode.val = value;
            moveListNodeToHead(listNode);
            return;
        } 
        if (hashMap.size() == capacity) {
            //删除最后一个
           ListNode delNode = removeLast();
           hashMap.remove(delNode.key);
        }
        
        ListNode newNode = new ListNode(key, value);
        hashMap.put(key, newNode);
        addListNodeToHead(newNode);
        
    }
}

/**
 * Your LRUCache object will be instantiated and called as such:
 * LRUCache obj = new LRUCache(capacity);
 * int param_1 = obj.get(key);
 * obj.put(key,value);
 */

面试题 17.12. BiNode

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    private TreeNode dummy;
    private TreeNode cur;
    private void convert(TreeNode root) {
        if (root == null) return;
        convert(root.left);
        cur.right = root;
        root.left = null;
        cur = root;
        convert(cur.right);
    }
    public TreeNode convertBiNode(TreeNode root) {
        dummy = new TreeNode(-1);
        cur = dummy;
        convert(root);
        return dummy.right;
    }
}

剑指 Offer 07. 重建二叉树

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    private HashMap<Integer, Integer> hashMap;
    private TreeNode buildTree(int[] preorder, int preStart, int preEnd, int[] inorder, int inStart, int inEnd){
        if (preStart >= preEnd || inStart >= inEnd) return null;
        int val = preorder[preStart];
        int index = hashMap.get(val);
        int leftIn = index - inStart;
        TreeNode treeNode = new TreeNode(val);
        treeNode.left = buildTree(preorder, preStart  + 1, preStart + 1 + leftIn, inorder, inStart, index);
        treeNode.right = buildTree(preorder, preStart + 1 + leftIn, preEnd, inorder, index + 1, inEnd);
        return treeNode;
    }
    public TreeNode buildTree(int[] preorder, int[] inorder) {
        hashMap = new HashMap<>();
        for (int i = 0; i < inorder.length; i++){
            hashMap.put(inorder[i], i);
        }
        return buildTree(preorder, 0, preorder.length, inorder, 0, inorder.length);
    }
}

剑指 Offer 27. 二叉树的镜像

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    private void swap(TreeNode root) {
        TreeNode temp = root.left;
        root.left = root.right;
        root.right = temp;
    }
    public TreeNode mirrorTree(TreeNode root) {
        if (root == null) return root;
        mirrorTree(root.left);
        mirrorTree(root.right);
        swap(root);
        return root;
    }
}

剑指 Offer 28. 对称的二叉树

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    private boolean isSymmetric(TreeNode leftNode, TreeNode rightNode) {
        if (leftNode == null && rightNode == null) return true;
        if (leftNode == null || rightNode == null) return false;
        if (leftNode.val != rightNode.val) return false;
        if (!isSymmetric(leftNode.left, rightNode.right)) return false;
        return isSymmetric(leftNode.right, rightNode.left);
    }
    public boolean isSymmetric(TreeNode root) {
        if (root == null) return true;
        return isSymmetric(root.left, root.right);
    }
}

剑指 Offer 32 - III. 从上到下打印二叉树 III

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    public List<List<Integer>> levelOrder(TreeNode root) {
        List<List<Integer>> result = new LinkedList<>();
        if (root == null) return result;
        Queue<TreeNode> queue = new LinkedList<>();
        queue.offer(root);
        int count = 0;
        while (!queue.isEmpty()){
            int size = queue.size();
            count++;
            LinkedList<Integer> list = new LinkedList<>();
            while (size-- > 0){
                TreeNode treeNode = queue.poll();
                if (count % 2 == 0) {
                    //从右往左
                    list.addFirst(treeNode.val);
                }  else {
                    //从左往有
                    list.addLast(treeNode.val);
                }
                if (treeNode.left != null) queue.offer(treeNode.left);
                if (treeNode.right != null) queue.offer(treeNode.right);
            }
            result.add(list);
        }
        return result;
    }
}

剑指 Offer 33. 二叉搜索树的后序遍历序列

class Solution {
    private boolean verifyPostorder(int[] postorder, int left, int right) {
        if (left >= right) return true;
        int m = left;
        while (m < right) {
            if (postorder[m] > postorder[right]) break; 
            m++;
        }
        
        while (m < right) {
            if (postorder[m] < postorder[right]) return false;
            m++;
        }
        return verifyPostorder(postorder, left, m - 1) && verifyPostorder(postorder, m, right - 1);
    }
    public boolean verifyPostorder(int[] postorder) {
        if (postorder == null || postorder.length == 0) return true;
        return verifyPostorder(postorder, 0, postorder.length - 1);
    }
}

剑指 Offer 54. 二叉搜索树的第k大节点

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    private int result;
    private int count;
    private boolean traver(TreeNode root, int k) {
        if (root == null) return false;
        boolean isFind = traver(root.right, k);
        if (isFind) return true;
        count++;
        if (count == k) {
            result = root.val;
            return true;
        }
        return traver(root.left, k);
    }
    public int kthLargest(TreeNode root, int k) {
        if (root == null) return -1;
        traver(root, k);
        return result;
    }
}

80. 删除有序数组中的重复项 II

class Solution {
    public int removeDuplicates(int[] nums) {
        int j = 0;
        int count = 0;
        for (int i = 1; i < nums.length; i++) {
           if (nums[i] != nums[j]) {
               nums[++j] = nums[i];
               count = 0;
           } else {
               count++;
               if (count >= 2) {

               } else {
                   nums[++j] = nums[i];
               }
           }
        }
        return ++j;
    }
}

125. 验证回文串

class Solution {
    private boolean isLeeterOrNum(char c) {
        if (c >= 'a' && c <= 'z') return true;
        if (c >= '0' && c <= '9') return true;
        return false;
    }
    public boolean isPalindrome(String s) {
        s = s.toLowerCase();
        int left = 0;
        int right = s.length() - 1;
        while (left < right) {

            if (!isLeeterOrNum(s.charAt(left))) {
                left++;
                continue;
            }
            if (!isLeeterOrNum(s.charAt(right))) {
                right--;
                continue;
            }
            if (s.charAt(left) != s.charAt(right)) return false;
            left++;
            right--;
        }
        return true;

    }
}

345. 反转字符串中的元音字母

class Solution {
    private boolean isYuanYin(String str, char ch) {
        return str.indexOf(ch) != -1;
    }
    public String reverseVowels(String s) {
        String yuan = "aeiouAEIOU";
        char[] ss = s.toCharArray();
        int left = 0;
        int right = ss.length - 1;
        while (left < right) {
            if (!isYuanYin(yuan, ss[left])) {
                left++;
                continue;
            }
            if (!isYuanYin(yuan, ss[right])) {
                right--;
                continue;
            }
            //交换
            char temp = ss[left];
            ss[left] = ss[right];
            ss[right] = temp;
            left++;
            right--;
        }
        return new String(ss);
    }
}
上一篇下一篇

猜你喜欢

热点阅读