算法常见习题2

一.链表

1.翻转链表(过)

import java.util.*;

/*
 * public class ListNode {
 *   int val;
 *   ListNode next = null;
 *   public ListNode(int val) {
 *     this.val = val;
 *   }
 * }
 */

public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param head ListNode类 
     * @return ListNode类
     */
    public ListNode ReverseList (ListNode head) {
        // write code here
        if(head == null || head.next == null){
            return head;
        }
        ListNode cur = head.next;
        head.next = null;
        while(cur != null){
            ListNode curNext = cur.next;
            cur.next = head;
            head = cur;
            cur = curNext;
        }
        return head;
    }
}

2.指定区间翻转链表(过)

import java.util.*;

/*
 * public class ListNode {
 *   int val;
 *   ListNode next = null;
 *   public ListNode(int val) {
 *     this.val = val;
 *   }
 * }
 */

public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param head ListNode类 
     * @param m int整型 
     * @param n int整型 
     * @return ListNode类
     */
    public ListNode reverseBetween (ListNode head, int m, int n) {
        // write code here
        if(head == null || m <= 0 || n <= 0){
            return null;
        }
        ListNode node = new ListNode(-1);
        node.next = head;
        ListNode tmp = node;
        for(int i = 0;i < m - 1;i++){
            tmp = tmp.next;
        }
        ListNode cur = tmp.next;
        for(int i = 0;i < n - m;i++){
            ListNode curNext = cur.next;
            cur.next = curNext.next;
            curNext.next = tmp.next;
            tmp.next = curNext;
        }
        return node.next;
    }
}

3. 链表中的节点每k个一组翻转

import java.util.*;

/*
 * public class ListNode {
 *   int val;
 *   ListNode next = null;
 *   public ListNode(int val) {
 *     this.val = val;
 *   }
 * }
 */

public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param head ListNode类 
     * @param k int整型 
     * @return ListNode类
     */
    public ListNode reverseKGroup (ListNode head, int k) {
        // write code here
        if(head == null || head.next == null || k <= 0){
            return head;
        }
        ListNode node = new ListNode(-1);
        node.next = head;
        ListNode per = head;
        for(int i = 0;i < k;i++){
            if(per == null){
                return head;
            }
            per = per.next;
        }
        ListNode cur = node.next;
        while(cur != per){
            ListNode curNext = cur.next;
            cur.next = node;
            node = cur;
            cur = curNext;
        }
        head.next = reverseKGroup(per,k);
        return node;
    }
}

4.合并两个有序链表(过)

import java.util.*;

/*
 * public class ListNode {
 *   int val;
 *   ListNode next = null;
 *   public ListNode(int val) {
 *     this.val = val;
 *   }
 * }
 */

public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param pHead1 ListNode类 
     * @param pHead2 ListNode类 
     * @return ListNode类
     */
    public ListNode Merge (ListNode pHead1, ListNode pHead2) {
        // write code here
        if(pHead1 == null && pHead2 == null){
            return null;
        }
        ListNode node = new ListNode(-1);
        ListNode tmp = node;
        while(pHead1 != null && pHead2 != null){
            if(pHead1.val > pHead2.val){
                tmp.next = pHead2;
                pHead2 = pHead2.next;
                tmp = tmp.next;
            }else{
                tmp.next = pHead1;
                pHead1 = pHead1.next;
                tmp = tmp.next;
            }
        }
        if(pHead1 != null){
            tmp.next = pHead1;

        }
        if(pHead2 != null){
            tmp.next = pHead2;
        }
        return node.next;
    }
}

5.合并k个已排序的链表

import java.util.*;

/*
 * public class ListNode {
 *   int val;
 *   ListNode next = null;
 *   public ListNode(int val) {
 *     this.val = val;
 *   }
 * }
 */

public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param lists ListNode类ArrayList 
     * @return ListNode类
     */
    public ListNode Merge (ListNode pHead1, ListNode pHead2) {
        // write code here
        if(pHead1 == null && pHead2 == null){
            return null;
        }
        ListNode node = new ListNode(-1);
        ListNode tmp = node;
        while(pHead1 != null && pHead2 != null){
            if(pHead1.val > pHead2.val){
                tmp.next = pHead2;
                pHead2 = pHead2.next;
                tmp = tmp.next;
            }else{
                tmp.next = pHead1;
                pHead1 = pHead1.next;
                tmp = tmp.next;
            }
        }
        if(pHead1 != null){
            tmp.next = pHead1;

        }
        if(pHead2 != null){
            tmp.next = pHead2;
        }
        return node.next;
    }
    public ListNode diver(ArrayList<ListNode> lists,int left,int right){
        if(left > right){
            return null;
        }else if(left == right){
            return lists.get(left);
        }else{
            int mid = (left + right) >> 1;
            return Merge(diver(lists,left,mid),diver(lists,mid + 1,right));
        }
    }
    public ListNode mergeKLists (ArrayList<ListNode> lists) {
        // write code here
        return diver(lists,0,lists.size() - 1);
    }
}

6.判断链表中是否有环(过)

import java.util.*;
/**
 * Definition for singly-linked list.
 * class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
public class Solution {
    public boolean hasCycle(ListNode head) {
        if(head == null || head.next == null){
            return false;
        }
        ListNode fast = head;
        ListNode slow = head;
        while(fast != null && fast.next != null){
            fast = fast.next.next;
            slow = slow.next;
            if(slow == fast){
                return true;
            }
        }
        return false;
    }
}

7. 链表中环的入口结点(过)

import java.util.*;
/*
 public class ListNode {
    int val;
    ListNode next = null;

    ListNode(int val) {
        this.val = val;
    }
}
*/
public class Solution {

    public ListNode EntryNodeOfLoop(ListNode pHead) {
        if(pHead == null || pHead.next == null){
            return null;
        }
        ListNode fast = pHead;
        ListNode slow = pHead;
        while(fast != null && fast.next != null){
            fast = fast.next.next;
            slow = slow.next;
            if(fast == slow){
                break;
            }
        }
        if(fast == null || fast.next == null){
            return null;
        }
        fast = pHead;
        while(fast != slow){
            fast = fast.next;
            slow = slow.next;
        }
        return slow;
    }
}

8.链表中倒数最后k个结点(过)

import java.util.*;

/*
 * public class ListNode {
 *   int val;
 *   ListNode next = null;
 *   public ListNode(int val) {
 *     this.val = val;
 *   }
 * }
 */

public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param pHead ListNode类 
     * @param k int整型 
     * @return ListNode类
     */
    public ListNode FindKthToTail (ListNode pHead, int k) {
        // write code here
        if(pHead == null || k <= 0){
            return null;
        }
        ListNode fast = pHead;
        ListNode slow = pHead;
        while(k-- > 0){
            if(fast == null){
                return null;
            }
            fast = fast.next;
        }
        while(fast != null){
            fast = fast.next;
            slow = slow.next;
        }
        return slow;
    }
}

9.删除链表的倒数第n个节点

import java.util.*;

/*
 * public class ListNode {
 *   int val;
 *   ListNode next = null;
 *   public ListNode(int val) {
 *     this.val = val;
 *   }
 * }
 */

public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param head ListNode类 
     * @param n int整型 
     * @return ListNode类
     */
    public ListNode removeNthFromEnd (ListNode head, int n) {
        // write code here
        if(head == null || n <= 0){
            return head;
        }
        ListNode node = new ListNode(-1);
        node.next = head;
        ListNode tmp = node;
        ListNode fast = head;
        while(n-- > 0){
            if(fast == null){
                return head;
            }
            fast = fast.next;
        }
        ListNode slow = head;
        while(fast != null){
            fast = fast.next;
            slow = slow.next;
            tmp = tmp.next;
        }
        tmp.next = slow.next;
        return node.next;
    }
}

10.两个链表的第一个公共结点(过)

import java.util.*;
/*
public class ListNode {
    int val;
    ListNode next = null;

    ListNode(int val) {
        this.val = val;
    }
}*/
public class Solution {
    public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) {
        if(pHead1 == null || pHead2 == null){
            return null;
        }
        int len1 = 0;
        int len2 = 0;
        ListNode p1 = pHead1;
        ListNode p2 = pHead2;
        while(p1 != null){
            p1 = p1.next;
            len1++;
        }
        while(p2 != null){
            p2 = p2.next;
            len2++;
        }
        int len = len1 - len2;
        if(len < 0){
            len = -len;
            p1 = pHead2;
            p2 = pHead1;
        }else{
            p1 = pHead1;
            p2 = pHead2;
        }
        while(len-- > 0){
            p1 = p1.next;
        }
        while(p1 != null && p2 != null){
            if(p1 == p2){
                return p1;
            }
            p1 = p1.next;
            p2 = p2.next; 
        }
        return null;
    }
}

11.链表相加

解法一:借助翻转链表

import java.util.*;

/*
 * public class ListNode {
 *   int val;
 *   ListNode next = null;
 *   public ListNode(int val) {
 *     this.val = val;
 *   }
 * }
 */

public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param head1 ListNode类 
     * @param head2 ListNode类 
     * @return ListNode类
     */

    //翻转链表
    public ListNode reverse(ListNode head){
        if(head == null || head.next == null){
            return head;
        }
        ListNode cur = head.next;
        head.next = null;
        while(cur != null){
            ListNode curNext = cur.next;
            cur.next = head;
            head = cur;
            cur = curNext;
        }
        return head;
    }
    public ListNode addInList (ListNode head1, ListNode head2) {
        // write code here
        if(head1 == null){
            return head2;
        }
        if(head2 == null){
            return head1;
        }
        head1 = reverse(head1);
        head2 = reverse(head2);
        ListNode node = new ListNode(-1);
        ListNode tmp = node;
        int carray = 0;//进位位数
        while(head1 != null || head2 != null || carray != 0){
            int val1 = (head1 == null) ? 0 : head1.val;
            int val2 = (head2 == null) ? 0 : head2.val;
            int num = val1 + val2 + carray;
            carray = num / 10;
            num %= 10;
            tmp.next = new ListNode(num);
            tmp = tmp.next;
            if(head1 != null){
                head1 = head1.next;
            }
            if(head2 != null){
                head2 = head2.next;
            }
        }
        return reverse(node.next);
    }
}

解法二:借用栈

import java.util.*;

/*
 * public class ListNode {
 *   int val;
 *   ListNode next = null;
 *   public ListNode(int val) {
 *     this.val = val;
 *   }
 * }
 */

public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param head1 ListNode类 
     * @param head2 ListNode类 
     * @return ListNode类
     */
    public ListNode addInList (ListNode head1, ListNode head2) {
        // write code here
        Stack<Integer> stack1 = new Stack<>();
        Stack<Integer> stack2 = new Stack<>();
        while(head1 != null){
            stack1.push(head1.val);
            head1 = head1.next;
        }
        while(head2 != null){
            stack2.push(head2.val);
            head2 = head2.next;
        }
        ListNode node = null;
        ListNode tmp = null;
        int carray = 0;
        while(!stack1.empty() || !stack2.empty() || carray != 0){
            int val1 = (stack1.empty()) ? 0 : stack1.pop();
            int val2 = (stack2.empty()) ? 0 : stack2.pop();
            int num = val1 + val2 + carray;
            carray = num / 10;
            num = num % 10;
            node = new ListNode(num);
            node.next = tmp;
            tmp = node;
        }
        return tmp;
    }
}

12.单链表的排序

import java.util.*;

/*
 * public class ListNode {
 *   int val;
 *   ListNode next = null;
 *   public ListNode(int val) {
 *     this.val = val;
 *   }
 * }
 */

public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param head ListNode类 the head node
     * @return ListNode类
     */
    // 合并链表
    public ListNode merge(ListNode head1,ListNode head2){
        if(head1 == null && head2  == null){
            return null;
        }
        ListNode node = new ListNode(-1);
        ListNode tmp = node;
        while(head1 != null && head2 != null){
            if(head1.val < head2.val){
                tmp.next = head1;
                head1 = head1.next;
                tmp = tmp.next;
            }else{
                tmp.next = head2;
                head2 = head2.next;
                tmp = tmp.next;
            }
        }
        if(head1 != null){
            tmp.next = head1;
        }
        if(head2 != null){
            tmp.next = head2;
        }
        return node.next;
    }
    public ListNode sortInList (ListNode head) {
        // write code here
        if(head == null || head.next == null){
            return head;
        }
        ListNode left = head;
        ListNode mid = head.next;
        ListNode right = head.next.next;
        // 找到链表的中间节点
        while(right != null && right.next != null){
            left = left.next;
            mid = mid.next;
            right = right.next.next;
        }
        left.next = null;
        // 合并分开的链表
        return merge(sortInList(head),sortInList(mid));
    }
}

13.判断一个链表是否是回文结构(过)

import java.util.*;

/*
 * public class ListNode {
 *   int val;
 *   ListNode next = null;
 *   public ListNode(int val) {
 *     this.val = val;
 *   }
 * }
 */

public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param head ListNode类 the head
     * @return bool布尔型
     */
    public boolean isPail (ListNode head) {
        // write code here
        if(head == null || head.next == null){
            return true;
        }
        ListNode fast = head;
        ListNode slow = head;
        // 找到中间节点slow
        while(fast != null && fast.next != null){
            fast = fast.next.next;
            slow = slow.next;
        }
        // 翻转中间节点后面的结点
        ListNode cur = slow.next;
        while(cur != null){
            ListNode curNext = cur.next;
            cur.next = slow;
            slow = cur;
            cur = curNext;
        }
        while(slow != head){
            if(slow.val != head.val){
                return false;
            }
            // 说明是由偶数个结点
            if(head.next == slow){
                return true;
            }
            head = head.next;
            slow = slow.next;
        }
        // 说明是奇数个结点,且是回文
        return true;
    }
}

14.链表的奇偶重排(过)

import java.util.*;

/*
 * public class ListNode {
 *   int val;
 *   ListNode next = null;
 *   public ListNode(int val) {
 *     this.val = val;
 *   }
 * }
 */

public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param head ListNode类 
     * @return ListNode类
     */
    public ListNode oddEvenList (ListNode head) {
        // write code here
        if(head == null || head.next == null){
            return head;
        }
        ListNode cur = head;
        ListNode curNext = cur.next;
        ListNode tmp = curNext;
        // 将奇数位和偶数位的结点分别组成一个新的链表
        while(curNext != null && curNext.next != null){
            cur.next = curNext.next;
            cur = cur.next;
            curNext.next = curNext.next.next;
            curNext = curNext.next;
        }
        // 连接奇数和偶数排列后的结果
        cur.next = tmp;
        return head;
    }
}

15.删除有序链表中重复的元素-I(过)

import java.util.*;

/*
 * public class ListNode {
 *   int val;
 *   ListNode next = null;
 *   public ListNode(int val) {
 *     this.val = val;
 *   }
 * }
 */

public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param head ListNode类 
     * @return ListNode类
     */
    public ListNode deleteDuplicates (ListNode head) {
        // write code here
        if(head == null || head.next == null){
            return head;
        }
        ListNode cur = head;
        ListNode curNext = cur.next;
        while(cur != null && curNext != null){
            if(cur.val == curNext.val){
                cur.next = curNext.next;
                curNext = curNext.next;
            }else{
                cur = curNext;
                curNext = cur.next;
            }
        }
        return head;

    }
}

16.删除有序链表中重复的元素-II(过)

import java.util.*;

/*
 * public class ListNode {
 *   int val;
 *   ListNode next = null;
 *   public ListNode(int val) {
 *     this.val = val;
 *   }
 * }
 */

public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param head ListNode类 
     * @return ListNode类
     */
    public ListNode deleteDuplicates (ListNode head) {
        // write code here
        if(head == null || head.next == null){
            return head;
        }
        ListNode node = new ListNode(-1);
        node.next = head;
        ListNode tmp = node;
        ListNode cur = head;
        boolean falg = false;
        while(cur != null && cur.next != null){
            if(cur.val == cur.next.val){
                cur = cur.next;
                falg = true;
            }else{
                // 当前结点与下一个节点的值不相等,且需要删除结点,需要修改指向
                if(falg == true){
                    tmp.next = cur.next;
                    cur = cur.next;
                    falg = false;
                }else{
                    // 当前结点与下一个节点的值不相等,但不需要删除结点
                    cur = cur.next;
                    tmp = tmp.next;
                }
                    
            }
        }
        // 需要删除最后一个节点
        if(falg == true){
            tmp.next = null;
        }
        return node.next;
    }
}

二、二分查找/排序

1.二分查找-1

import java.util.*;


public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param nums int整型一维数组 
     * @param target int整型 
     * @return int整型
     */
    public int search (int[] nums, int target) {
        // write code here
        if(nums == null || nums.length == 0){
            return -1;
        }
        int left = 0;
        int right = nums.length - 1;
        while(left <= right){
            int mid = (left + right) /2;
            if(nums[mid] < target){
                left = mid + 1;
            }else if(nums[mid] > target){
                right = mid - 1;
            }else{
                return mid;
            }
        }
        return -1;
    }
}

2.二维数组中的查找

import java.util.*;


public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param target int整型 
     * @param array int整型二维数组 
     * @return bool布尔型
     */
    public boolean Find (int target, int[][] array) {
        // write code here
        if(array == null || array.length == 0){
            return false;
        }
        int i = 0;
        int j = array[0].length - 1;
        while(i < array.length && j >= 0){
            if(array[i][j] > target){
                j--;
            }else if(array[i][j] < target){
                i++;
            }else if(array[i][j] == target){
                return true;
            }
        }
        return false;
    }
}

3.寻找峰值

import java.util.*;


public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param nums int整型一维数组 
     * @return int整型
     */
    public int findPeakElement (int[] nums) {
        // write code here
        if(nums == null || nums.length == 0){
            return -1;
        }
        int left = 0;
        int right = nums.length - 1;
        while(left < right){
            int mid = (left + right) / 2;
            // 右边的值往下不一定有山峰
            if(nums[mid] > nums[right]){
                right = mid;
            }else{
                // 右边的值往上一定有山峰
                left = mid + 1;
            }
        }
        return right;
    }
}

4.数组中的逆序对

import java.util.*;


public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     *
     * @param nums int整型一维数组
     * @return int整型
     */
    public int mod = 1000000007;
    // 计算逆序对的个数
    public int reversePairs(int[] nums, int[] temp, int left, int right) {
        if (left >= right) {
            return 0;
        }
        int mid = (left + right) >> 1;
        // 左边逆序对的个数
        int leftReverse = reversePairs(nums, temp, left, mid);
        // 右边逆序对的个数
        int rightReverse = reversePairs(nums, temp, mid + 1, right);
        // 两边排序完成后逆序对的个数
        int countReverse = merge(nums, temp, left, mid, right);
        return (leftReverse + rightReverse + countReverse) % mod;
    }
    // 此时[left,mid]和[mid + 1,right]是有序的
    private int merge(int[] nums, int[] temp, int left, int mid, int right) {
        for (int i = left; i <= right; i++) {
            temp[i] = nums[i];
        }
        // 此时i 和 j 分别指向要合并的两个数组的第一个元素
        int i = left;
        int j = mid + 1;
        int count = 0;
        for (int k = left; k <= right; k++) {
            // i == mid + 1说明左边的已经归并完成
            if (i == mid + 1) {
                nums[k] = temp[j];
                j++;
            } else if (j == right + 1 || temp[i] <= temp[j]) {
                // j == right + 1说明右边的已经归并完成
                // temp[i] <= temp[j]说明右边的数字大,就将左边的进行归并
                nums[k] = temp[i];
                i++;
            } else {
                // 将右边数组的元素进行归并且进行逆序对的统计
                nums[k] = temp[j];
                j++;
                count += mid - i + 1;
            }
        }
        return count % mod;
    }
    public int InversePairs (int[] nums) {
        // write code here
        int[] temp = new int[nums.length];
        return reversePairs(nums, temp, 0, nums.length - 1);
    }
}
public class Solution {
    public int mod = 1000000007;
    public int mergeSort(int left,int right,int[] nums,int[] temp){
        if(left >= right){
            return 0;
        }
        int mid = (left + right) >> 1;
        int result = mergeSort(left,mid,nums,temp) + mergeSort(mid + 1,right,nums,temp);
        result %= mod;
        for(int i = left;i <= right;i++){
            temp[i] = nums[i];
        }
        // 此时i 和 j 分别指向要合并的两个数组的第一个元素
        int i = left;
        int j = mid + 1;
        for(int k = left;k <= right;k++){
            // i == mid + 1说明左边的已经归并完成
            if(i == mid + 1){
                nums[k] = temp[j];
                j++;
            }else if(j == right + 1 || temp[i] <= temp[j]){
                // j == right + 1说明右边的已经归并完成
                // temp[i] <= temp[j]说明右边的数字大,就将左边的进行归并
                nums[k] = temp[i];
                i++;
            } else{
                // 将右边数组的元素进行归并且进行逆序对的统计
                nums[k] = temp[j];
                j++;
                result += mid - i + 1;
            }
        }
        return result % mod;
    }
    public int InversePairs(int[] array) {
        int[] result = new int[array.length];
        return mergeSort(0,array.length - 1,array,result);
    }
}

5.旋转数组中的最小数字

import java.util.*;


public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param nums int整型一维数组 
     * @return int整型
     */
    public int minNumberInRotateArray (int[] nums) {
        // write code here
        if(nums == null || nums.length == 0){
            return -1;

        }
        int i = 0;
        int j = nums.length - 1;
        int mid = 0;
        while(nums[i] >= nums[j]){
            if(j - i == 1){
                return nums[j];
            }
             mid = (i + j ) >> 1;
            if(nums[i] == nums[mid] && nums[j] == nums[i]){
                int result = nums[i];
                for(int k = i;k < j;k++){
                    if(nums[k] < result){
                        result = nums[k];
                    }
                }
                return result;
            }
            if(nums[mid] >= nums[i]){
                i = mid;
            }else{
                j = mid;
            }
        }
        return nums[mid];
    }
}

6.比较版本号

import java.util.*;


public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 比较版本号
     * @param version1 string字符串 
     * @param version2 string字符串 
     * @return int整型
     */
    public int compare (String version1, String version2) {
        // write code here
        int length1 = version1.length();
        int length2 = version2.length();
        int start1 = 0;
        int start2 = 0;
        while(start1 < length1 || start2 < length2){
            long num1 = 0;
            // 将每个点号之前的字符串转化为整数,进行比较
            while(start1 < length1 && version1.charAt(start1) != '.'){
                num1 = num1 * 10 + version1.charAt(start1) - '0';
                start1++;
            }
            start1++;//跳过点号
            long num2 = 0;
            while(start2 < length2 && version2.charAt(start2) != '.'){
                num2 = num2 * 10 + version2.charAt(start2) - '0';
                start2++;
            }
            start2++;//跳过点号
            // version1 < version2
            if(num1 < num2){
                return -1;
            }else if(num1 > num2){
            // version1 > version2
                return 1;
            }
        }
        return 0;
    }
}

三、二叉树

1.二叉树的前序遍历

import java.util.*;

/*
 * public class TreeNode {
 *   int val = 0;
 *   TreeNode left = null;
 *   TreeNode right = null;
 *   public TreeNode(int val) {
 *     this.val = val;
 *   }
 * }
 */

public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param root TreeNode类 
     * @return int整型一维数组
     */
    public void preorder(ArrayList<Integer> list,TreeNode root){
        if(root == null){
            return;
        }
        list.add(root.val);
        preorder(list,root.left);
        preorder(list,root.right);
    }
    public int[] preorderTraversal (TreeNode root) {
        // write code here
        ArrayList<Integer> list = new ArrayList<>();
        preorder(list,root);
        int[] result = new int[list.size()];
        for(int i = 0;i < result.length;i++){
            result[i] = list.get(i);
        }
        return result;
    }
}

2.二叉树的中序遍历

import java.util.*;

/*
 * public class TreeNode {
 *   int val = 0;
 *   TreeNode left = null;
 *   TreeNode right = null;
 *   public TreeNode(int val) {
 *     this.val = val;
 *   }
 * }
 */

public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param root TreeNode类 
     * @return int整型一维数组
     */
    public void inorder(ArrayList<Integer> list,TreeNode root){
        if(root == null){
            return;
        }
        inorder(list,root.left);
        list.add(root.val);
        inorder(list,root.right);
    }
    public int[] inorderTraversal (TreeNode root) {
        // write code here
        ArrayList<Integer> list = new ArrayList<>();
        inorder(list,root);
        int[] result = new int[list.size()];
        for(int i = 0;i < result.length;i++){
            result[i] = list.get(i);
        }
        return result;
    }
}

3.二叉树的后续遍历

import java.util.*;

/*
 * public class TreeNode {
 *   int val = 0;
 *   TreeNode left = null;
 *   TreeNode right = null;
 *   public TreeNode(int val) {
 *     this.val = val;
 *   }
 * }
 */

public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param root TreeNode类 
     * @return int整型一维数组
     */
    public void postorder(ArrayList<Integer> list,TreeNode root){
        if(root == null){
            return;
        }
        postorder(list,root.left);
        postorder(list,root.right);
        list.add(root.val);
    }
    public int[] postorderTraversal (TreeNode root) {
        // write code here
        ArrayList<Integer> list = new ArrayList<>();
        postorder(list,root);
        int[] result = new int[list.size()];
        for(int i = 0;i < result.length;i++){
            result[i] = list.get(i);
        }
        return result;
    }
}

4.求二叉树的层序遍历

import java.util.*;

/*
 * public class TreeNode {
 *   int val = 0;
 *   TreeNode left = null;
 *   TreeNode right = null;
 *   public TreeNode(int val) {
 *     this.val = val;
 *   }
 * }
 */

public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param root TreeNode类 
     * @return int整型ArrayList<ArrayList<>>
     */
    public ArrayList<ArrayList<Integer>> levelOrder (TreeNode root) {
        // write code here
        ArrayList<ArrayList<Integer>> result = new ArrayList<>();
        if(root == null){
            return result;
        }
        Queue<TreeNode> queue = new LinkedList<>();
        queue.offer(root);
        while(!queue.isEmpty()){
            ArrayList<Integer> list = new ArrayList<>();
            int n = queue.size();
            while(n-- > 0){
                TreeNode tmp = queue.poll();
                list.add(tmp.val);
                if(tmp.left != null){
                    queue.offer(tmp.left);
                }
                if(tmp.right != null){
                    queue.offer(tmp.right);
                }
            }
            result.add(list);
            
        }
        return result;
    }
}

5.按之字形顺序打印二叉树

import java.util.*;

/*
 * public class TreeNode {
 *   int val = 0;
 *   TreeNode left = null;
 *   TreeNode right = null;
 *   public TreeNode(int val) {
 *     this.val = val;
 *   }
 * }
 */

public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param pRoot TreeNode类 
     * @return int整型ArrayList<ArrayList<>>
     */
    public ArrayList<ArrayList<Integer>> Print (TreeNode pRoot) {
        // write code here
        ArrayList<ArrayList<Integer>> result = new ArrayList<>();
        if(pRoot == null){
            return result;
        }
        Stack<TreeNode> stack = new Stack<>();
        Queue<TreeNode> queue = new LinkedList<>();
        stack.push(pRoot);
        boolean flag = true;
        while(!stack.isEmpty()){
            ArrayList<Integer> list = new ArrayList<>();
            while(!stack.empty()){
                TreeNode tmp = stack.pop();
                list.add(tmp.val);
                TreeNode first = (flag == true) ? tmp.left : tmp.right;
                TreeNode second = (flag == true) ? tmp.right : tmp.left;
                if(first != null){
                    queue.offer(first);
                }
                if(second != null){
                    queue.offer(second);
                }
            }
            result.add(list);
            while(!queue.isEmpty()){
                stack.push(queue.poll());
            }
            flag = (flag == true) ? false : true;
        }
        return result;
    }
}

6.二叉树的最大深度

import java.util.*;

/*
 * public class TreeNode {
 *   int val = 0;
 *   TreeNode left = null;
 *   TreeNode right = null;
 *   public TreeNode(int val) {
 *     this.val = val;
 *   }
 * }
 */

public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param root TreeNode类 
     * @return int整型
     */
    public int maxDepth (TreeNode root) {
        // write code here
        if(root == null){
            return 0;
        }
        Queue<TreeNode> queue = new LinkedList<>();
        queue.offer(root);
        int depth = 0;
        while(!queue.isEmpty()){
            int n = queue.size();
            depth++;
            for(int i = 0;i < n;i++){
                TreeNode tmp = queue.poll();
                if(tmp.left != null){
                    queue.offer(tmp.left);
                }
                if(tmp.right != null){
                    queue.offer(tmp.right);
                }
            }
        }
        return depth;
    }
}
import java.util.*;

/*
 * public class TreeNode {
 *   int val = 0;
 *   TreeNode left = null;
 *   TreeNode right = null;
 *   public TreeNode(int val) {
 *     this.val = val;
 *   }
 * }
 */

public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param root TreeNode类 
     * @return int整型
     */
    public int maxDepth (TreeNode root) {
        // write code here
        if(root == null){
            return 0;
        }
        return Math.max(maxDepth(root.left),maxDepth(root.right)) + 1;
    }
}

7.二叉树中和为某一值的路径

import java.util.*;

/*
 * public class TreeNode {
 *   int val = 0;
 *   TreeNode left = null;
 *   TreeNode right = null;
 *   public TreeNode(int val) {
 *     this.val = val;
 *   }
 * }
 */

public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param root TreeNode类 
     * @param sum int整型 
     * @return bool布尔型
     */
    public boolean hasPathSum (TreeNode root, int sum) {
        // write code here
        if(root == null){
            return false;
        }
        // 当前结点是叶子结点且路径的和为sum
        if(root.left == null && root.right == null && sum - root.val == 0){
            return true;
        }
        // 递归查看左右结点
        return hasPathSum(root.left,sum-root.val) || hasPathSum(root.right,sum-root.val);
    }
}

8.二叉搜索树与双向链表

在这里插入图片描述

import java.util.*;
/**
public class TreeNode {
    int val = 0;
    TreeNode left = null;
    TreeNode right = null;

    public TreeNode(int val) {
        this.val = val;

    }

}
*/
public class Solution {
    public TreeNode prev = null;
    // 二叉搜索树中序遍历的结果就是有序的
    public void ConvertChild(TreeNode root){
        if(root == null){
            return;
        }
        ConvertChild(root.left);
        root.left = prev;
        if(prev != null){
            prev.right = root;
        }
        prev = root;
        ConvertChild(root.right);
    }
    public TreeNode Convert(TreeNode pRootOfTree) {
        if(pRootOfTree == null){
            return null;
        }
        // 调整
        ConvertChild(pRootOfTree);
        // 从树的根结点向前找,直到左节点为空就说明是链表的头
        TreeNode head = pRootOfTree;
        while(head.left != null){
            head = head.left;
        }
        return head;
    }
}

9.对称的二叉树

import java.util.*;

/*
 * public class TreeNode {
 *   int val = 0;
 *   TreeNode left = null;
 *   TreeNode right = null;
 *   public TreeNode(int val) {
 *     this.val = val;
 *   }
 * }
 */

public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param pRoot TreeNode类 
     * @return bool布尔型
     */
    public boolean isSymmetricalChild(TreeNode root1,TreeNode root2){
        if(root1 == null && root2 == null){
            return true;
        }
        if(root1 == null || root2 == null || root1.val != root2.val){
            return false;
        }
        return isSymmetricalChild(root1.left,root2.right) && isSymmetricalChild(root1.right,root2.left);
    }
    public boolean isSymmetrical (TreeNode pRoot) {
        // write code here
        return isSymmetricalChild(pRoot,pRoot);
    }
}

10.合并二叉树

import java.util.*;

/*
 * public class TreeNode {
 *   int val = 0;
 *   TreeNode left = null;
 *   TreeNode right = null;
 *   public TreeNode(int val) {
 *     this.val = val;
 *   }
 * }
 */

public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param t1 TreeNode类 
     * @param t2 TreeNode类 
     * @return TreeNode类
     */
    public TreeNode mergeTrees (TreeNode t1, TreeNode t2) {
        // write code here
        if(t1 == null){
            return t2;
        }
        if(t2 == null){
            return t1;
        }
        TreeNode root = new TreeNode(t1.val + t2.val);
        root.left = mergeTrees(t1.left,t2.left);
        root.right = mergeTrees(t1.right,t2.right);
        return root;
    }
}

11. 二叉树的镜像

import java.util.*;

/*
 * public class TreeNode {
 *   int val = 0;
 *   TreeNode left = null;
 *   TreeNode right = null;
 *   public TreeNode(int val) {
 *     this.val = val;
 *   }
 * }
 */

public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param pRoot TreeNode类 
     * @return TreeNode类
     */
    public TreeNode Mirror (TreeNode pRoot) {
        // write code here
        if(pRoot == null){
            return null;
        }
        TreeNode tmp = pRoot.left;
        pRoot.left = pRoot.right;
        pRoot.right = tmp;
        Mirror(pRoot.left);
        Mirror(pRoot.right);
        return pRoot;
    }
}

12. 判断是不是二叉搜索树

import java.util.*;

/*
 * public class TreeNode {
 *   int val = 0;
 *   TreeNode left = null;
 *   TreeNode right = null;
 *   public TreeNode(int val) {
 *     this.val = val;
 *   }
 * }
 */

public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param root TreeNode类 
     * @return bool布尔型
     */
    // 将pre初始化为int的最小值
    public int pre = Integer.MIN_VALUE;
    public boolean isValidBST (TreeNode root) {
        // write code here
        if(root == null){
            return true;
        }
        // 向左递归
        if(!isValidBST(root.left)){
            return false;
        }
        // 如果前一个节点的值大于当前结点的值,返回false
        if(root.val < pre){
            return false;
        }
        // 存下当前结点的值,下一次递归就是当前结点的前一个节点
        pre = root.val;
        return isValidBST(root.right);
    }
}

13.判断是不是完全二叉树

import java.util.*;

/*
 * public class TreeNode {
 *   int val = 0;
 *   TreeNode left = null;
 *   TreeNode right = null;
 *   public TreeNode(int val) {
 *     this.val = val;
 *   }
 * }
 */

public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param root TreeNode类 
     * @return bool布尔型
     */
    public boolean isCompleteTree (TreeNode root) {
        // write code here
        if(root == null){
            return true;
        }
        Queue<TreeNode> queue = new LinkedList<>();
        queue.offer(root);
        boolean flag = false;
        while(!queue.isEmpty()){
            TreeNode tmp = queue.poll();
            // 找到第一次出现空节点的位置
            if(tmp == null){
                flag = true;
                continue;
            }
            // 如果flag为真,说明提前出现了叶子结点
            if(flag){
                return false;
            }
            queue.offer(tmp.left);
            queue.offer(tmp.right);
        }
        return true;
    }
}

14.判断是不是平衡二叉树

import java.util.*;

/*
 * public class TreeNode {
 *   int val = 0;
 *   TreeNode left = null;
 *   TreeNode right = null;
 *   public TreeNode(int val) {
 *     this.val = val;
 *   }
 * }
 */

public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param pRoot TreeNode类 
     * @return bool布尔型
     */
    // 计算树的深度
    public int depth(TreeNode pRoot){
        if(pRoot == null){
            return 0;
        }
        return Math.max(depth(pRoot.left),depth(pRoot.right)) + 1;
    }
    public boolean IsBalanced_Solution (TreeNode pRoot) {
        // write code here
        if(pRoot == null){
            return true;
        }
        int leftDepth = depth(pRoot.left);
        int rightDepth = depth(pRoot.right);
        // 左右子树之差不大于1
        if(leftDepth - rightDepth > 1 || rightDepth - leftDepth > 1){
            return false;
        }
        // 看左右子树是否是平衡二叉树
        return IsBalanced_Solution(pRoot.left) && IsBalanced_Solution(pRoot.right);
    }
}

15.二叉搜索树的最近公共祖先

import java.util.*;

/*
 * public class TreeNode {
 *   int val = 0;
 *   TreeNode left = null;
 *   TreeNode right = null;
 *   public TreeNode(int val) {
 *     this.val = val;
 *   }
 * }
 */

public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     *
     * @param root TreeNode类
     * @param p int整型
     * @param q int整型
     * @return int整型
     */
    public int lowestCommonAncestor (TreeNode root, int p, int q) {
        // write code here
        if (root == null) {
            return -1;
        }
        if (root.val == p || root.val == q) {
            return root.val;
        }
        int leftTree = lowestCommonAncestor(root.left, p, q);
        int rightTree = lowestCommonAncestor(root.right, p, q);
        // 要查询的公共结点的两个结点在root的两边
        if (leftTree != -1 && rightTree != -1) {
            return root.val;
        }
        // 要查询的公共结点的两个结点在root的左边
        if (leftTree != -1) {
            return leftTree;
        }
        // 要查询的公共结点的两个结点在root的右边
        if (rightTree != -1) {
            return rightTree;
        }
        return -1;
    }
}

16.序列化二叉树

import java.util.*;
/*
public class TreeNode {
    int val = 0;
    TreeNode left = null;
    TreeNode right = null;

    public TreeNode(int val) {
        this.val = val;

    }

}
*/
public class Solution {
    // 序列化
    String Serialize(TreeNode root) {
        if (root == null) {
            return "#";
        }
        StringBuffer sb = new StringBuffer();
        Queue<TreeNode> queue = new LinkedList<>();
        queue.offer(root);
        while (!queue.isEmpty()) {
            TreeNode tmp = queue.poll();
            if (tmp == null) {
                sb.append("#,");
            } else {
                sb.append(tmp.val + ",");
                if (tmp.left != null) {
                    queue.offer(tmp.left);
                } else {
                    queue.offer(null);
                }
                if (tmp.right != null) {
                    queue.offer(tmp.right);
                } else {
                    queue.offer(null);
                }
            }
        }
        return new String(sb);
    }
    // 反序列化
    TreeNode Deserialize(String str) {
        if (str.equals("#")) {
            return null;
        }
        String[] s = str.split(",");
        TreeNode root = new TreeNode(Integer.parseInt(s[0]));
        Queue<TreeNode> queue = new LinkedList<>();
        queue.offer(root);
        int i = 1;
        while(!queue.isEmpty()){
            TreeNode tmp = queue.poll();
            String left = s[i++];
            String right = s[i++];
            if(left.equals("#")){
                tmp.left = null;
            }else{
                TreeNode leftTree = new TreeNode(Integer.parseInt(left));
                tmp.left = leftTree;
                queue.offer(leftTree);
            }
            if(right.equals("#")){
                tmp.right = null;
            }else{
                TreeNode rightTree = new TreeNode(Integer.parseInt(right));
                tmp.right = rightTree;
                queue.offer(rightTree);
            }
        }
        return root;
    }
}

17.重建二叉树

import java.util.*;

/*
 * public class TreeNode {
 *   int val = 0;
 *   TreeNode left = null;
 *   TreeNode right = null;
 *   public TreeNode(int val) {
 *     this.val = val;
 *   }
 * }
 */

public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param preOrder int整型一维数组 
     * @param vinOrder int整型一维数组 
     * @return TreeNode类
     */
    public TreeNode reConstructBinaryTreeChild(int[] preOrder,int preStart,int preEnd,int[] vinOrder,int vinStart,int vinEnd){
        if(preStart > preEnd || vinStart > vinEnd){
            return null;
        }
        TreeNode root = new TreeNode(preOrder[preStart]);
        for(int i = vinStart;i <= vinEnd;i++){
            if(vinOrder[i] == root.val){
                root.left = reConstructBinaryTreeChild(preOrder,preStart + 1,i - vinStart + preStart,vinOrder,vinStart,i - 1);
                root.right = reConstructBinaryTreeChild(preOrder,i - vinStart + preStart + 1,preEnd,vinOrder,i + 1,vinEnd);
            }
        }
        return root;
    }
    public TreeNode reConstructBinaryTree (int[] preOrder, int[] vinOrder) {
        // write code here
        if(preOrder == null || vinOrder == null){
            return null;
        }
        return reConstructBinaryTreeChild(preOrder,0,preOrder.length-1,vinOrder,0,vinOrder.length - 1);
    }
}

18.输出二叉树的右视图

import java.util.*;


public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值blank即可
     *
     * 求二叉树的右视图
     * @param preOrder int整型一维数组 先序遍历
     * @param inOrder int整型一维数组 中序遍历
     * @return int整型一维数组
     */
    // 根据前序遍历和中序遍历的结果构建二叉树
    public TreeNode build(int[] preOrder, int preStart,int preEnd, int[] vinOrder, int vinStart, int vinEnd) {
        if (preStart > preEnd || vinStart > vinEnd) {
            return null;
        }
        TreeNode root = new TreeNode(preOrder[preStart]);
        for (int i = vinStart; i <= vinEnd; i++) {
            if (vinOrder[i] == root.val) {
                root.left = build(preOrder, preStart + 1,i - vinStart + preStart, vinOrder, vinStart, i - 1);
                root.right = build(preOrder, i - vinStart + preStart + 1,preEnd, vinOrder, i + 1, vinEnd);
            }
        }
        return root;
    }
    // 层序遍历这棵二叉树将每一层的最右边的元素添加到顺序表中
    public ArrayList<Integer> levelOrder(TreeNode root){
        ArrayList<Integer> list = new ArrayList<>();
        Queue<TreeNode> queue = new LinkedList<>();
        queue.offer(root);
        while(!queue.isEmpty()){
            int size = queue.size();
            for(int i = 0;i < size;i++){
                TreeNode tmp = queue.poll();
                if(tmp.left != null){
                    queue.offer(tmp.left);
                }
                if(tmp.right != null){
                    queue.offer(tmp.right);
                }
                // 将最右边的元素添加到list中
                if(i == size - 1){
                    list.add(tmp.val);
                }
            }
        }
        return list;
    }
    public int[] solve (int[] preOrder, int[] inOrder) {
        // write code here
        if(preOrder == null || inOrder == null){
            return null;
        }
        // 建树
        TreeNode root = build(preOrder,0,preOrder.length - 1,inOrder,0,inOrder.length - 1);
        // 获取右视图
        ArrayList<Integer> list = levelOrder(root);
        // 转换为数组输出
        int[] result = new int[list.size()];
        for(int i = 0;i < list.size();i++){
            result[i] = list.get(i);
        }
        return result;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值