数据结构之链表:实现单链表的k逆序(2)

有一个单链表,请设计一个算法,使得每K个节点之间逆序,如果最后不够K个节点一组,则不调整最后几个节点。例如链表1->2->3->4->5->6->7->8->null,K=3这个例子。调整后为,3->2->1->6->5->4->7->8->null。因为K==3,所以每三个节点之间逆序,但其中的7,8不调整,因为只有两个节点不够一组。

给定一个单链表的头指针head,同时给定K值,返回逆序后的链表的头指针。





/*
struct ListNode {
    int val;
    struct ListNode *next;
    ListNode(int x) : val(x), next(NULL) {}
};*/
class KInverse {
public:

    //这是我有一篇博客中描述的单链表逆序的函数 照搬过来的 
    ListNode* reverse(ListNode* head){
        if(head==NULL){
            return NULL;
        }
        auto cur=head;
        ListNode* pre=NULL;
        while(cur!=NULL){
            auto pnext=cur->next;
            cur->next=pre;
            pre=cur;
            cur=pnext;
        }
        return pre;
        
    }


    
    
    ListNode* inverse(ListNode* head, int k) {
        // write code here
        if(head==NULL){
            return NULL;
        }
        int i=1;  //注意i是从1开始,结束时p指针指向NULL,i最后的值要比结点数多1。
        ListNode* p=head;   //p是遍历指针
        ListNode* pre=head; //pre记录每次做逆序的起始点
        ListNode* phead=NULL; //逆序后的头结点 
        ListNode* pend=NULL; //每次逆序k长度结点后,逆序完的那个尾结点。
                             //如果一个链表为1->2->3->4,那么pend逆序完指向1,phead指向3。 
       
        
        while(p!=NULL){
            if(i%k==0){    // i刚好是k的倍数 
                auto q=p->next;
                p->next=NULL;  //   这个很容易遗漏 如果1->2->3>4  p指针刚好走到3 要将3->next=NULL 否则一直逆序到底 
                if(phead==NULL){
                    phead=reverse(pre);
                }
                else{
                    pend->next=reverse(pre);
                }
                pend=pre;
                pre=q;
                p=pre;        
            }
            else{
                p=p->next;
            }
            i++;      
        }
        if(i-1             return head;
        }
        if((i-1)%k>0){
            pend->next=pre;  // i最后除以k有余数 表明还有个数小于k几个结点 不能逆序 我们直接将pend连接到这几个结点的头结点
        }
        return phead;
    }   
    


};

你可能感兴趣的:(面试题)