链表(拆分,反转,合并)

本文介绍了一种在不改变节点值的情况下,对单链表进行重排序的算法。通过快慢指针找到中点,将链表分为两部分,然后反转后半部分链表,并交替合并两部分链表,实现重排序。

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

题目描述

 

Given a singly linked list LL 0→L 1→…→L n-1→L n,
reorder it to: L 0→L n →L 1→L n-1→L 2→L n-2→…

You must do this in-place without altering the nodes' values.

For example,
Given{1,2,3,4}, reorder it to{1,4,2,3}.

package xidian.lili.haoweilai;

import java.util.ArrayList;
import java.util.Scanner;
import java.util.Stack;

class ListNode {
	int val;
	ListNode next;

	ListNode(int x) {
		val = x;
		next = null;
	}
}

public class Demo01 {
	public void reorderList(ListNode head) {
		if(head==null || head.next==null){
			return;
		}
		ListNode fast=head;
		ListNode slow=head;
		while(fast.next!=null && fast.next.next!=null){
			slow=slow.next;
			fast=fast.next.next;
		}
		ListNode after=slow.next;//后半部分链表
		slow.next=null;//断开
		//反转链表
		ListNode pre=null;
		while(after!=null){
			ListNode temp=after.next;//保存当前节点的下一个节点
			after.next=pre;
			pre=after;
			after=temp;
		}
		//合并两条链表
		ListNode first=head;
		after=pre;
		while(first!=null && after!=null){
			ListNode ftemp=first.next;
			ListNode atemp=after.next;
			first.next=after;
			after.next=ftemp;
			after=after.next;
			first=ftemp;
			after=atemp;
		}

	}
}

 

### 实现链表重排的操作 链表的重排操作通常涉及将一个链表按照某种特定的方式重新排列。常见的方法之一是从中间拆分链表并将后半部分反转,之后交替合并两个子链表[^3]。 以下是基于上述描述的具体实现方式: #### 输入与输出 - **输入**: 给定一个单向链表 `head`。 - **输出**: 返回经过重排后的链表头节点。 #### 主要步骤说明 1. 找到链表的中点并将其分为两部分。可以使用快慢指针法来找到中点位置[^2]。 2. 对第二部分链表进行反转处理。 3. 合并前半部分和已反转的后半部分链表,形成新的交错形式。 下面是具体的 Python 和 C++ 的代码示例: --- #### Python 实现 ```python class ListNode: def __init__(self, val=0, next=None): self.val = val self.next = next def reorderList(head: ListNode) -> None: if not head or not head.next: return # Step 1: 使用快慢指针找到链表的中点 slow, fast = head, head while fast and fast.next: slow = slow.next fast = fast.next.next # 断开链表为前后两部分 second_half = slow.next slow.next = None # Step 2: 反转后半部分链表 prev, curr = None, second_half while curr: temp = curr.next curr.next = prev prev = curr curr = temp reversed_second_half = prev # Step 3: 合并前半部分和反转后的后半部分 first, second = head, reversed_second_half while second: tmp_first, tmp_second = first.next, second.next first.next = second second.next = tmp_first first, second = tmp_first, tmp_second ``` --- #### C++ 实现 ```cpp #include <iostream> using namespace std; struct ListNode { int val; ListNode *next; ListNode(int x) : val(x), next(nullptr) {} }; void reorderList(ListNode* head) { if (!head || !head->next) return; // Step 1: Find the middle of the list using slow-fast pointers ListNode *slow = head, *fast = head; while (fast && fast->next) { slow = slow->next; fast = fast->next->next; } // Split the list into two halves ListNode *second_half = slow->next; slow->next = nullptr; // Step 2: Reverse the second half of the list ListNode *prev = nullptr, *curr = second_half; while (curr) { ListNode *temp = curr->next; curr->next = prev; prev = curr; curr = temp; } ListNode *reversed_second_half = prev; // Step 3: Merge the two lists alternately ListNode *first = head, *second = reversed_second_half; while (second) { ListNode *tmp_first = first->next, *tmp_second = second->next; first->next = second; second->next = tmp_first; first = tmp_first; second = tmp_second; } } ``` --- 通过以上两种语言的实现可以看出,整个过程的关键在于如何高效地完成三个阶段的任务:寻找中点、反转链表以及最终的合并操作。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值