我正在尝试解决这个问题:"在给定的链接列表中排列元素,使得所有偶数都放在奇数之后。元素的各个顺序应保持不变。"
这是我正在使用的代码:
class Node<T> {
T data;
Node<T> next;
Node(T data) {
this.data = data;
}
}
这是主要逻辑:
static Node<Integer> sortOddEven(Node<Integer> head) {
if(head == null || head.next == null) {
return head;
}
Node<Integer> middle = getMiddle(head);
Node<Integer> nextOfMiddle = middle.next;
middle.next = null;
Node<Integer> temp1 = sortOddEven(head);
Node<Integer> temp2 = sortOddEven(nextOfMiddle);
Node<Integer> sortedList = sortOddEvenMerger(temp1, temp2);
return sortedList;
}
static Node<Integer> sortOddEvenMerger(Node<Integer> head1, Node<Integer> head2) {
Node<Integer> head3 = null, tail3 = null;
if(head1.data.intValue()%2 != 0) {
head3 = head1;
tail3 = head1;
head1 = head1.next;
} else {
head3 = head2;
tail3 = head2;
head2 = head2.next;
}
while(head1 != null || head2 != null) {
if(head1 == null) {
tail3.next = head2;
return head3;
} else if(head2 == null){
tail3.next = head1;
return head3;
}
if(head1.data.intValue()%2 != 0) {
tail3.next = head1;
tail3 = tail3.next;
head1 = head1.next;
} else {
tail3.next = head2;
tail3 = tail3.next;
head2 = head2.next;
}
}
tail3.next = null;
return head3;
}
基本上我已经稍微调整了MergeSort
算法来解决这个问题,如果我遇到奇数元素,我先在sortOddEvenMerger
方法中添加它们,然后在它们之后添加元素。但元素的相对顺序会发生变化。
示例:输入 - 1 4 5 2
预期产出 - 1 5 4 2
我的输出 - 1 5 2 4
如何更多调整以维持相对顺序?
答案 0 :(得分:7)
你的方法不仅使问题比现在更困难,而且效率也更低,因为如果我正确理解它是O(nlgon)
。这是因为您正在尝试实施mergesort算法,并对奇数(和偶数)元素进行排序,从而导致错误的结果。
一个简单的算法:
制作两个最初为空的新列表(一个用于偶数元素的奇数列表)。
遍历主列表并将奇数列表中找到的每个奇数元素和偶数列表中的每个偶数元素相加。对于遍历,O(n)
为每个列表中的每次插入O(1)
。
当主列表中没有任何元素时,你有两个奇数 - 甚至是具有正确顺序的元素的列表,所以只需链接它们以获得一个具有预期输出的列表 - 这一步也是O(1)
! / p>
总复杂度:O(n)。(其中n是主列表的长度)。
答案 1 :(得分:0)
此问题的 Python 代码:
def evenAfterOdd(head):
if head is None:
return head
end = head
prev = None
curr = head
# Get pointer to last Node
while (end.next != None):
end = end.next
new_end = end
# Consider all even nodes before getting first odd node
while (curr.data % 2 != 1 and curr != end):
new_end.next = curr
curr = curr.next
new_end.next.next = None
new_end = new_end.next
# do following steps only if there is an odd node
if (curr.data % 2 == 1):
head = curr
# now curr points to first odd node
while (curr != end):
if (curr.data % 2 == 1):
prev = curr
curr = curr.next
else:
# Break the link between prev and curr
prev.next = curr.next
# Make next of curr as None
curr.next = None
# Move curr to odd
new_end.next = curr
# Make curr as new odd of list
new_end = curr
# Update curr pointer
curr = prev.next
# We have to set prev before executing rest of this code
else:
prev = curr
if (new_end != end and end.data % 2 != 1):
prev.next = end.next
end.next = None
new_end.next = end
return head