[leetcode] MergedKSortedList && ReversedNodesinKGroup

  • 第一题:MergedKSortedList
    • 题意:给定了K个有序单向的list的第一个节点,让给返回将这K个List合并后的List的首节点
    • 思路1:每次比较K个list的当前节点,选出最小的,加入result的list中。直到K个list都遍历完成。
    • 思路2:2分法合并,首先利用二分法将其分成两两list,然后再合并两两list,直到最后合并完成。
    • 思路3:利用最优队列,将所有点加入到最优队列中去,排序的依据就是节点的val从小到大排序。然后再一次将所有点弹出即可。
    • 三种方法的代码代码如下,这三种方法的耗时逐渐减少,具体耗时见下图:
struct ListNode {
    int val;
    ListNode *next;
    ListNode(int x) : val(x), next(NULL) {}
    ListNode* ListNodeFromVector(vector<int> xs){
        ListNode* head = this;
        for(int i=0;i<xs.size();i++){
            head->next = new ListNode(xs[i]);
            head = head->next;
        }
        return this->next;
    }
    void print(){
        ListNode* head = this;
        while(head != NULL){
            cout<<head->val<<"->";
            head = head->next;
        }
        cout<<endl;
    }
};
struct cmp{
    bool operator()(ListNode* a, ListNode* b){
        return a->val>b->val;
    }
};
class Solution {
public:
    ListNode* mergeBinaryList(ListNode* l1, ListNode* l2){
        ListNode* res = new ListNode(0);
        ListNode* head = res;
        while(l1 != NULL && l2 != NULL){
            if(l1->val < l2->val){
                res->next = new ListNode(l1->val);
                l1 = l1->next;
                res = res->next;
            }else{
                res->next = new ListNode(l2->val);
                l2 = l2->next;
                res = res->next;
            }
        }
        if(l1 != NULL){
            res->next = l1;
        }
        if(l2 != NULL){
            res->next = l2;
        }
        return head->next;
    }
    // 时间复杂度O(Nlog(k))
    ListNode* binary_divided(vector<ListNode*>& lists, int s, int e){
        if(s == e){
            return lists[s];
        }else{
            if(s < e){
                int mid = (s + e) / 2;
                ListNode* l1 = binary_divided(lists, s, mid);
                ListNode* l2 = binary_divided(lists, mid + 1, e);
                return mergeBinaryList(l1, l2);
            }else{
                return NULL;
            }
        }
    }
    // 时间复杂度O(kN)
    void generate(vector<ListNode*>& lists, ListNode* head){
        //head->print();
        ListNode** min_node = NULL;
        for(int i=0;i<lists.size();i++){
            if(lists[i] != NULL){
                if(min_node == NULL){
                    min_node = &lists[i];
                }else{
                    if((*min_node)->val > lists[i]->val){
                        min_node = &lists[i];
                    }
                }
            }else{
                continue;
            }
        }
        if(min_node == NULL){
            return ;
        }
        head->next = new ListNode((*min_node)->val);
        *min_node = (*min_node)->next;
        generate(lists, head->next);
    }
    // 时间复杂度O(Nlog(k))
    ListNode* priority_queue_method(vector<ListNode* > lists){
        priority_queue<int, vector<int >, greater<int> > queue1;
        for(int i=0;i<lists.size();i++){
            ListNode* head = lists[i];
            while(head != NULL){
                queue1.push(head->val);
                head = head->next;
            }
        }
        ListNode* res = new ListNode(0);
        ListNode* head = res;
        while(not queue1.empty()){
            res->next = new ListNode(queue1.top());
            queue1.pop();
            res = res->next;
        }
        return head->next;

    }
    ListNode* priority_queue_method_v2(vector<ListNode* > lists){
        priority_queue<ListNode*, vector<ListNode* >, cmp> queue1;
        for(int i=0;i<lists.size();i++){
            // ListNode* head = lists[i];
            if(lists[i] != NULL)
                queue1.push(lists[i]);
        }
        ListNode* res = new ListNode(0);
        ListNode* head = res;
        while(not queue1.empty()){
            ListNode* top = queue1.top();
            res->next = new ListNode(top->val);
            queue1.pop();
            res = res->next;
            if(top->next != NULL){
                queue1.push(top->next);
            }
        }
        return head->next;

    }
    ListNode* mergeKLists(vector<ListNode*>& lists) {
//        ListNode* head = new ListNode(0);
//        generate(lists, head);
//        return head->next;
        // return binary_divided(lists, 0, lists.size()-1);
        // return priority_queue_method(lists);
        return priority_queue_method_v2(lists);
    }
};

在这里插入图片描述

  • 第二题:ReversedNodesinKGroup
    • 题意:给定一个list的首节点,和一个数字K,返回将该list每隔K个元素reverse 的list的首节点。例如:1->2->3->4->5, K=2,那么结果便是2->1->4->3->5.
    • 思路1 (暴力):利用queue和stack组合的形式。首先将所有节点加入队列queue1中,然后再取K个元素,加入stack中,再从stack中取出这K个元素,加入队列。然后再从队列中取K个元素,加入stack。直到队列为空。该方法的空间复杂度较高
    • 思路2:本方法的空间复杂度为常熟级别。我们先想一想如何调转list中的某K个元素。我们先得到K个元素的第一个node l(指针,下同)、l+k=r个指针、l的前一个元素jump。让cur=l, pre = r; 然后让cur->next = pre;cur=cur(original)->next; pre=cur(original); 迭代上述K次。此时cur指向的就是r,pre指向的就是r的前一个元素。此时我们可以让jump->next就等于pre(原K个元素中的最后一个元素)。jump=l(原K个元素中的第一个元素,也是下一个K个元素中第一个元素的上一个元素)。l=cur or r(下一个K个元素中过的第一个元素);
    • 具体方法举例如下:
    
    head->a->b->c->d->e->NEXT
    =>
    head->a->NEXT || b->c->d->e->NEXT
    =>
    head->a || b->a->NEXT || c->d->e->NEXT
    =>
    ...
    =>
    head->a || e->d->c->b->a->NEXT
    =>
    head->e->d->c->b->a->NEXT
    
    • 代码如下:
struct ListNode {
    int val;
    ListNode *next;
    ListNode(int x) : val(x), next(NULL) {}
    ListNode* ListNodeFromVector(vector<int> xs){
        ListNode* head = this;
        for(int i=0;i<xs.size();i++){
            head->next = new ListNode(xs[i]);
            head = head->next;
        }
        return this->next;
    }
    void print(){
        ListNode* head = this;
        while(head != NULL){
            cout<<head->val<<"->";
            head = head->next;
        }
        cout<<endl;
    }
};
class Solution {
public:
    ListNode* reverseKGroup_v2(ListNode* head, int k){
        ListNode *res = new ListNode(0);
        ListNode *front_head = res;
        res->next = head;
        // front_head->next = head;
        ListNode* l = head;
        ListNode* r = head;

        while(true){
            // res->next->print();
            int count = 0;
            while(count<k && r != NULL){
                r = r->next;
                count += 1;
            }
            // cout<<"r is "<<r->val<<endl;
            if(count == k){
                ListNode* pre = r;
                ListNode* cur = l;
                for(int i=0;i<count;i++){
                    ListNode* second = cur->next;
                    cur->next = pre;
                    ListNode* original_cur = cur;
                    cur = second;
                    pre = original_cur;
                }
                front_head->next = pre;
                front_head = l;
                l = r;

            }else{
                // 结束了
                return res->next;
            }
        }
    }
    ListNode* reverseKGroup(ListNode* head, int k) {
        queue<int > xs;
        while(head != NULL){
            xs.push(head->val);
            head = head->next;
        }
        ListNode* tmp = new ListNode(0);
        ListNode* res = tmp;
        while(xs.size() >= k){
            stack<int> xs_stack;
            for(int i=0;i<k;i++){
                xs_stack.push(xs.front());
                xs.pop();
            }
            while(not xs_stack.empty()){
                tmp->next = new ListNode(xs_stack.top());
                xs_stack.pop();
                tmp = tmp->next;
            }
        }
        while(not xs.empty()){
            tmp->next = new ListNode(xs.front());
            xs.pop();
            tmp = tmp->next;
        }
        return res->next;
    }
};	
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值