对链表进行插入排序

对链表进行插入排序

描述

对链表进行插入排序。

插入排序的动画演示如上。从第一个元素开始,该链表可以被认为已经部分排序(用黑色表示)。
每次迭代时,从输入数据中移除一个元素(用红色表示),并原地将其插入到已排好序的链表中。

插入排序算法:

插入排序是迭代的,每次只移动一个元素,直到所有元素可以形成一个有序的输出列表。
每次迭代中,插入排序只从输入数据中移除一个待排序的元素,找到它在序列中适当的位置,并将其插入。
重复直到所有输入数据插入完为止。

思路和代码

用tail表示排好序的链尾,用node表示当前遍历到的结点,用cur表示从dummy开始遍历到node应该插入的位置的前一个结点

class Solution {
public:
    ListNode* insertionSortList(ListNode* head) {
        if(head == NULL || head->next == NULL)
            return head;
        ListNode * dummy = new ListNode(-1);
        dummy -> next = head;

        ListNode * tail = head; //tail指向排好序的链尾
        ListNode * node = head->next;  //当前结点

        while(node){
            if(node->val < tail->val){ //若当前结点值比链尾值大,则不需要插入排序
                ListNode * cur = dummy;
                while(cur->next && node->val >  cur->next->val){
                    cur = cur->next;
                }
                tail->next = node->next;
                node->next = cur->next;
                cur->next =  node;
                node=tail->next;

            }else{
                tail = tail->next;
                node = tail->next;
            }
        }
        return dummy->next;
    }
};

缺失的第一个正数

描述

给你一个未排序的整数数组,请你找出其中没有出现的最小的正整数。

示例 1:

输入: [1,2,0]
输出: 3
示例 2:

输入: [3,4,-1,1]
输出: 2
示例 3:

输入: [7,8,9,11,12]
输出: 1

哈希
class Solution {
public:
    int firstMissingPositive(vector<int>& nums) {
        map<int, bool> hash;
        int len = nums.size();
        for(int i=0; i<len; i++){
            hash[nums[i]] = true;
        }
        for(int i=1; ; i++)
        {
            if(hash.find(i) == hash.end())
                return i;
        }
    }
};
桶排序

参考https://leetcode.wang/leetCode-41-First-Missing-Positive.html
本质上是桶排序 (bucket sort),每当 A[i]!= i+1 的时候,将 A[i] 与 A[A[i]-1] 交换,直到无法 交换为止,终止条件是 A[i]== A[A[i]-1]。小于等于0或者大于n的数不用交换,因为不会影响。

class Solution {
public:
    int firstMissingPositive(vector<int>& nums) { 
        int n = nums.size();
        bucket_sort(nums, n); 
        for (int i = 0; i < n; ++i) 
            if (nums[i] != (i + 1)) 
                return i + 1; 
        return n + 1; 
    } 
    
private: 
    void bucket_sort(vector<int>& A, int n) { 
        for (int i = 0; i < n; i++) { 
            while (A[i] != i + 1) { 
                if (A[i] <= 0 || A[i] > n || A[i] == A[A[i] - 1]) 
                    break; 
                swap(A[i], A[A[i] - 1]); 
            } 
        } 
    } 
};

颜色分类

描述

给定一个包含红色、白色和蓝色,一共 n 个元素的数组,原地对它们进行排序,使得相同颜色的元素相邻,并按照红色、白色、蓝色顺序排列。

此题中,我们使用整数 0、 1 和 2 分别表示红色、白色和蓝色。

注意:
不能使用代码库中的排序函数来解决这道题。

示例:

输入: [2,0,2,1,1,0]
输出: [0,0,1,1,2,2]

思路和代码

1.遍历一遍数组,得出0,1,2出现多少次,然后遍历数组,一一赋值即可

2.荷兰国旗问题

class Solution {
public:
    void sortColors(vector<int>& nums) {
        //荷兰国旗问题
        int start = 0, curr = 0;
        // 对于所有 idx > p2 : nums[idx > p2] = 2
        int end = nums.size() - 1;

        while (curr <= end) {
            if (nums[curr] == 0) {
                swap(nums[curr++], nums[start++]);
            }
            else if (nums[curr] == 2) {
                swap(nums[curr], nums[end--]);
            }
            else curr++;
        }
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值