Reverse Nodes in k-Group [逆转K-Group链表]

本文介绍了一种链表操作技巧,即如何将链表的节点分组,并对每组节点进行反转,适用于链表中特定节点数目的操作场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Given a linked list, reverse the nodes of a linked list k at a time and return its modified list.

If the number of nodes is not a multiple of k then left-out nodes in the end should remain as it is.

You may not alter the values in the nodes, only nodes itself may be changed.

Only constant memory is allowed.

For example,
Given this linked list: 1->2->3->4->5

For k = 2, you should return: 2->1->4->3->5

For k = 3, you should return: 3->2->1->4->5


public class Solution {
	public ListNode reverseKGroup(ListNode head, int k) {
		if(head==null){
			return null;
		}
		int len=1;
		int i=0;
		int group=0;
		int r=0;
		ListNode p=head;
		//获取链表长度
		while(p.next!=null){
			len++;
			p=p.next;
		}
		if(head.next==null || k>len){
			return head;
		}
		
		//计算整组总数
		group=len/k;
		r=len%k;
		
		//倒序节点
//		ListNode fNode=null,pNode=head,next;
//		while(pNode!=null){
//			next=pNode.next;
//			pNode.next=fNode;
//			fNode=pNode;//当前节点下一轮就是别人的next了
//			pNode=next;
//		}
//		head=fNode;
		ListNode pNode=head,rNode=null,nNode=null;
		//用于记录当前位置
		int index=0;
		for(i=0;i<group;i++){
			index=i*k;
			if(index==len-r-1){
				break;
			}
//			int startIndex=i*k;
			if(i==0){
				rNode=Solution.reversePart_(pNode, k);
			}else{
				nNode=pNode.next;
				Solution.reversePart(pNode, k);
				pNode=nNode;
			}
		}
		return rNode;
	}

	//获取指定位置的节点
	public static ListNode getListNodeForIndex(ListNode n,int l){
		while(n!=null && l>0){
			n=n.next;
			l--;
		}
		return n;
	}
	//逆转从n.next到指定长度l
	public static ListNode reversePart(ListNode pNode,int l){
		ListNode next=null,fNode=null,fistNode=null,n=pNode.next;
		fistNode=n;
		while(n!=null && l>0){
			next=n.next;
			n.next=fNode;
			fNode=n;
			n=next;
			l--;
		}
		if(n!=null){
			fistNode.next=n;
		}
		pNode.next=fNode;
		return fNode;
	} 
	//逆转从n到指定长度l
		public static ListNode reversePart_(ListNode n,int l){
			ListNode next=null,fNode=null,fistNode=null;
			fistNode=n;
			while(n!=null && l>0){
				next=n.next;
				n.next=fNode;
				fNode=n;
				n=next;
				l--;
			}
			if(n!=null){
				fistNode.next=n;
			}
			return fNode;
		} 

}


### 字节跳动公司面试中的算法题解析 #### 单链表反转问题及其变种 字节跳动公司在面试过程中经常考察候选人对于数据结构的理解以及实际编程能力。其中,单链表的操作是一个常见的考点之一。具体来说,有一类问题是要求从链表的尾部开始分组并进行操作[^2]。 这类问题的核心挑战在于单向链表无法直接反向访问节点。因此,解决方法通常涉及递归或者栈辅助实现倒序处理逻辑[^4]。下面通过具体的例子说明如何应对这一类型的题目: 假设我们需要设计一个函数 `reverseKGroup` 来完成以下功能: 输入为一个单链表头指针 `head` 和整数 `k` ,输出一个新的链表头指针表示经过修改后的列表形式——即每连续 k 个结点作为一个子序列被翻转;如果最后剩余不足 k 的部分保持原样不变。 以下是 Python 实现版本的一个可能解法: ```python class ListNode: def __init__(self, val=0, next=None): self.val = val self.next = next def reverseList(head: ListNode) -> ListNode: prev = None current = head while current is not None: temp_next = current.next current.next = prev prev = current current = temp_next return prev def reverseKGroup(head: ListNode, k: int) -> ListNode: count = 0 cur = head # Check if there are at least k nodes remaining. while cur and count < k: cur = cur.next count += 1 if count == k: reversedHead = reverseList(head) # Recursively call on the rest of the list after reversing first group. head.next = reverseKGroup(cur, k) return reversedHead else: return head ``` 上述代码片段展示了基于递归方式解决问题的方法论。它先判断当前是否有足够的长度来进行一次完整的 K 组交换动作,如果有,则执行局部逆转过程,并继续对后续链条应用相同策略直到结束条件满足为止。 另外值得注意的是,在准备此类技术岗位笔试或现场考核环节时,除了掌握基础理论外还需要注重实战演练效果提升效率[^3]。 #### 动态规划经典案例分析 除开针对特定数据结构的设计之外,动态规划也是另一项备受关注的能力领域。比如最长公共子串(LCS)计算就是非常典型的代表作之一[^5]: 设字符串A长度为m,B长度为n,定义二维数组dp[m+1][n+1],初始化全零边界值;接着按照状态转移关系逐步填充其余位置数值直至最终求得目标结果. 其核心思想可以总结如下两条规则用于更新每一个单元格内的最大匹配数量记录: - 当前字符相等时继承左上角相邻区域已积累成果加一; - 否则取上方或者左侧较大者延续路径追踪方向标记; 此方法时间复杂度O(m*n),空间消耗同样如此但在某些场景下允许进一步优化减少内存占用量级至线性级别即可满足需求标准.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值