LeetCode刷题之排序(持续更新)

1. 排序链表

148. 排序链表

在 O(n log n) 时间复杂度和常数级空间复杂度下,对链表进行排序。

示例 1:

输入: 4->2->1->3
输出: 1->2->3->4

示例 2:

输入: -1->5->3->4->0
输出: -1->0->3->4->5
 

public class Solution {
    /*
    思路:
    难点在于 时间复杂度限制在 O(nlogn),能达到这个复杂度的排序一般就是 快排,堆排序和归并排序,
    但是稳定的只有归并排序。至于常数空间复杂度,由于是链表操作,因此比较容易实现。
    因此,实际上就是归并排序的问题。
     */
    public ListNode sortList(ListNode head) {
        if (head == null || head.next == null) {
            return head;
        }
        ListNode fast = head;
        ListNode slow = head; //快慢节点 -> 链表中点
        while (fast.next != null && fast.next.next != null) {
            fast = fast.next.next;
            slow = slow.next;
        }
        ListNode mid = slow.next;
        slow.next = null;
        ListNode l1 = sortList(head);
        ListNode l2 = sortList(mid);
        ListNode sorted = Merge(l1, l2);
        return sorted;
    }

    //归并
    private ListNode Merge(ListNode l1, ListNode l2) {
        if (l1 == null) {
            return l2;
        }
        if (l2 == null) {
            return l1;
        }
        ListNode head, tmp;
        if (l1.val < l2.val) {
            head = l1;
            l1 = l1.next;
        } else {
            head = l2;
            l2 = l2.next;
        }
        tmp = head;
        while (l1 != null && l2 != null) {
            if (l1.val < l2.val) {
                tmp.next = l1;
                tmp = tmp.next;
                l1 = l1.next;
            } else {
                tmp.next = l2;
                tmp = tmp.next;
                l2 = l2.next;
            }
        }
        if (l1 == null) {
            tmp.next = l2;
        }
        if (l2 == null) {
            tmp.next = l1;
        }
        return head;
    }

}

2. 搜索旋转排序数组

33. 搜索旋转排序数组

假设按照升序排序的数组在预先未知的某个点上进行了旋转。

( 例如,数组 [0,1,2,4,5,6,7] 可能变为 [4,5,6,7,0,1,2] )。

搜索一个给定的目标值,如果数组中存在这个目标值,则返回它的索引,否则返回 -1 。

你可以假设数组中不存在重复的元素。

你的算法时间复杂度必须是 O(log n) 级别。

示例 1:

输入: nums = [4,5,6,7,0,1,2], target = 0
输出: 4

示例 2:

输入: nums = [4,5,6,7,0,1,2], target = 3
输出: -1
 

public class Solution {
    /*
    思路:
    二分查找(O(logN)的复杂度)
    这题说的旋转,实际上就是左右整体互换,也就导致出现了两个递增序列。
    也就是说当我们二分查找时,有两种可能,
    一种是选择的部分位于递增序列,而另一种可能选择的部分位于递减再递增的序列。
     */
    public int search(int[] nums, int target) {
        if (nums.length == 0) {
            return -1;
        }
        int st = 0, end = nums.length - 1;
        while (st <= end) {
            int mid = st + (end - st) / 2;
            if (nums[mid] == target) {
                return mid;
            }
            if (nums[mid] >= nums[st]) {
                if (nums[st] <= target && target < nums[mid]) {
                    end = mid - 1;
                } else {
                    st = mid + 1;
                }
            } else {
                if (nums[mid] < target && target <= nums[end]) {
                    st = mid + 1;
                } else {
                    end = mid == 0 ? mid : mid - 1;
                }
            }
        }
        return -1;
    }
}

猜你喜欢

转载自blog.csdn.net/qq_34519487/article/details/104668576