- 首先,题目有两个特殊输入,即空 或者k=1 该情况只需直接返回即可
- 下面考虑别的情况:
从第一个结点开始遍历
逆置的起点一定是从(n-1)k+1位 到 nk 如 123 k=3 逆置从1 到 3 n=1
由于只有每次遇到k的倍数位时开始逆置,逆置个数为k个,而当出现不满k个的组就不会进行逆置
我们考虑创建一个空的头结点,每次遍历到倍数nk时开始逆置,但是同时需要记录逆置的开始指针,以及所需的指针
例如: 12345 3 用q记录1 从1开始到3 用p记录3 r记录4
q:用于记录每个开始逆置的结点
p:用于记录当前结点情况 为中间或逆置开始 或逆置结束结点
r:用于记录逆置结束位的下一位 ,方便下一次进行逆置
这里采用了i=1记录每个结点情况,是否为 首 中 尾
- 若i%k==1,则令q=到当前位置; 此情况代表p遍历到了第(n-1)k+1位
- 若i%k==0,p为当前位置 ,r为当前位置的下一位,并开始逆置; 此情况代表p遍历到了nk位
- 其余情况, p往后移动
逆置:
tempHead=p; 注意:逆置结束后 p为新的头结点
(当q不为r时){//头插法
temp=q->next;
q->next=pre->next;
pre->next=q;
q=temp;
}
p=r;(回到i%k为1的情况 q=p;)
pre=tempHead;
当p为空时,要么结点全都接完了,要么位数不够,把剩余结点接入L即可
位数不够时 (n-1)k+2 <= i <= nk
如果(i-1)%k!=0 这里取i-1去取余
pre->next = q; 接入头结点
struct ListNode* reverseKGroup(struct ListNode* head, int k ) { // write code here //特殊情况 if(k <= 1 || head == NULL){ return head; } int i = 1; //创建一个头结点,便于反转 struct ListNode* L = (struct ListNode*)malloc(sizeof(struct ListNode)); L->next = NULL; struct ListNode *p,*pre,*q,*r,*tempHead; struct ListNode *temp; pre = L; p = head; while(p){ if(i % k == 1){ q = p; } if(i % k == 0){ //r指向 p 的下一个 temp 指向 q r = p->next; tempHead = q; //头插法 while(q!=r){ temp = q->next; q->next = pre->next; pre->next = q; q = temp; } p = r; pre = tempHead; }else{ p = p->next; } i++; } if((i-1) % k != 0){ pre->next = q; } return L->next;