ACM模式链表输入&手撕k组反转链表

 面试手撕的时候遇到了,自己没处理好,做过的题想不出来,气死,以此谨记。

 ACM模式链表输入

#include <iostream>
#include <vector>
using namespace std;
struct Node{
  int val;
  Node* next;
  Node(int v): val(v), next(nullptr){}
};
Node* creat(vector<int>& arr){
    Node* head = new Node(-1);
    Node* pre = head;
    for(auto& a:arr){
        Node* t = new Node(a);
        pre->next = t;
        pre = t;
    }
    return head;
}
int main(){
    vector<int> arr{1,2,3,4,5,6,7,8};
    Node* L = creat(arr);
    Node* t = L;//可选
    L = L->next;//记得!!!
    delete t;//可选
    t = nullptr;//可选
    /*
        调用你的函数方法
        t = func(L);
    */
    while(t != nullptr){
        cout << t->val;//打印
        Node* tmp = t;//可选
        t = t->next;  
        delete tmp; //可选
    }
    return 0;
}

k个一组反转链表Leetcode25

官方的简单操作:递归

拆分问题:每次反转1组

返回值:反转后的头节点

边界条件:空或长度不到k个

Node* reversek(Node* l, int k){
    if(k == 1 || l == nullptr) return l;
    Node* tail = l;
    for(int i = 0; i < k; ++i){//判断长度是否满足反转条件
        if(tail == nullptr) return l;
        tail = tail->next;
    }
    //循环结束时,tail指向下一组的头!
    Node* pre = l;
    Node* cur = l->next;
    while(cur != tail){//只需要处理k-1次
        Node* tmp = cur->next;
        cur->next = pre;
        pre = cur;
        cur = tmp;
    } 
    //循环结束时,pre指向反转后的新头,cur指向下一组的头。
    l->next = reversek(cur, k);//l是反转后的尾节点,递归反转下一组。
    return pre;
}

面试时手撕的复杂操作。。。 循环

Node* reversek(Node* l, int k,int len){
    if(k == 1) return l;
    Node *dummy = new Node(-1);
    dummy -> next = l;
    Node * pre = dummy;//分组的头节点的前置节点
    Node * cur = l;
    for(int i = 0; i + k <= len; i += k){
        Node * head = cur;//反转前的头 
        Node * p = cur;//处理反转的前置节点
        cur = cur->next;//从第二个节点开始处理反转
        for(int j = 0; j < k - 1; j++){//反转K-1次
            Node * tmp = cur->next;
            cur->next = p;
            p = cur;
            cur = tmp;
        }
        //循环结束时,p指向新的头,cur指向下一组的头
        head->next = cur;//反转前的头作为反转后的最后一个节点
        pre->next = p;//反转前的头的前置节点连接新头
        pre = head; //更新下一组头的前置节点
    }
    Node* res = dummy->next;
    delete dummy;
    return res;
}
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值