Java中,有一个整数单链表L,设计一个尽可能高效的算法将所有负整数的元素移动到其他元素前面。例如,L=(1,2,-1,-2,3,-3,4),移动后 L=(-1,-2,-3,1,2,3,4)。
时间: 2024-10-11 19:09:44 浏览: 26
在Java中,要高效地实现这个功能,可以采用“双指针”策略,同时维护两个指针,一个正向遍历链表(找到第一个非负元素并开始记录),另一个反向遍历链表(找到第一个负元素并反转从该位置开始的所有负数部分)。以下是具体的步骤:
1. 定义两个指针 `prev` 和 `current`,初始都指向链表头。
2. 当 `current` 指向的元素是非负数时,继续向前移动 `current`;如果它是负数,将 `prev` 设置为当前节点,然后将 `current` 移动到下一个负数节点。
3. 当 `current` 遍历到链表尾部时,说明已经处理完所有的正数,此时 `prev` 指向的是最后一个负数前的节点。从 `prev` 开始,将链表反转,直到链表尾部。
4. 最后返回原链表的头部。
这个算法的时间复杂度是O(n),其中n是链表的长度,因为每个元素只会被访问一次。
```java
class ListNode {
int val;
ListNode next;
ListNode(int x) { val = x; }
}
public ListNode moveNegativesToFront(ListNode head) {
if (head == null || head.next == null) return head;
ListNode prev = null, current = head;
while (current != null) {
if (current.val >= 0) {
// 正向查找第一个非负数
prev = current;
current = current.next;
} else {
// 反转从第一个负数开始的部分
ListNode negStart = prev;
while (negStart.next != null && negStart.next.val < 0) {
ListNode temp = negStart.next;
negStart.next = temp.next;
temp.next = prev;
prev = temp;
}
// 继续向前查找下一个负数
current = current.next;
}
}
// 将剩余的正数部分连接到反转后的负数部分
if (prev != null) {
prev.next = current;
}
return head;
}
```
阅读全文