[编程题]按照左右半区的方式重新组合单链表
时间限制:1秒 空间限制:32768K
给定一个单链表的头部节点head,链表长度为N。 如果N为偶数,那么前N/2个节点算作左半区,后N/2个节点算作右半区; 如果N为奇数,那么前N/2个节点算作左半区,后N/2+1个节点算作右半区; 左半区从左到右依次记为L1->L2->…,右半区从左到右依次记为R1->R2->…。请将单链表调整成L1->R1->L2->R2->…的样子。 例如: 1->2->3->4 调整后:1->3->2->4 1->2->3->4->5 调整后:1->3->2->4->5 要求:如果链表长度为N,时间复杂度请达到O(N),额外空间复杂度请达到O(1)
思路:
创建一个新Vector,先将整个链表push_back如心得Vector中,同时将其按下标分成左右两个链表,从前到后逐个判断”链表”(实则已是在Vector中操作)从头到尾的第奇数还是偶数位,Vector的奇数位插入原链表右侧元素,偶数为插入原链表左侧元素,直到链表(Vector)结束;
/*
* 按照左右半区的方式重新组合单链表
* 输入:一个单链表的头节点head
* 将链表调整成题目要求的样子
*/
class Solution {
public:
/*struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};*/
void relocateList(struct ListNode* pHead) {
ListNode* Pointer = pHead;
vector<int> Vector;
while (Pointer != NULL) {
Vector.push_back(Pointer->val);
Pointer = Pointer->next;
}
Pointer = pHead;
int IndexOfVector = 0;
int IndexOfLeft = 0;
int IndexOfRight = Vector.size() / 2;
while (IndexOfVector<Vector.size()-1 && Pointer != NULL) {
if (IndexOfVector % 2 == 0) {//链表偶数位(包括0)
Pointer->val = Vector[IndexOfLeft++];
Pointer = Pointer->next;
}
else if (IndexOfVector % 2 != 0) {//链表奇数位
Pointer->val = Vector[IndexOfRight++];
Pointer = Pointer->next;
}
++IndexOfVector;
}
}
};
解法2
class Solution {
public:
void relocateList(struct ListNode* head) {
ListNode* p = head ;
int length = 0 ;
while ( p != NULL ) {
++ length ;
p = p -> next ;
}
vector<int> vec ;
p = head ;
for ( int i = 0; i < length; ++ i ) {
vec.push_back( p->val ) ;
p = p->next ;
}
p = head ;
int left_cur = 0 ;
int right_cur = length / 2 ;
int index = 0 ;
while( index < vec.size() - 1 && p != NULL ) {
if ( index % 2 == 0 ) {
p->val = vec[left_cur] ;
++ left_cur ;
}
else {
p->val = vec[right_cur] ;
++ right_cur ;
}
p = p->next ;
++ index ;
}
}
};
【基本思路】
先遍历一遍找到左半区的最后一个节点,然后将链表分成左右两部分,在按照题目要求重新合并即可。
如何找到左半区的最后一个节点?
例如:1 -> 2,mid为1;
1 -> 2 -> 3,mid为2;
1 -> 2 -> 3 -> 4,mid为2;
1 -> 2 -> 3 -> 4 -> 5,mid为3;
1 -> 2 -> 3 -> 4 -> 5 -> 6,mid为3;
也就是说,从长度为2开始,长度每增加2,mid就往后移动一个节点。
Python实现
#python3.5
def reCombination(head):
if head == None or head.next == None:
return head
mid = head
right = head.next
while right.next != None and right.next.next != None:
mid = mid.next
right = right.next.next
right = mid.next
mid.next = None
cur = head
while cur.next != None:
rightNext = right.next
right.next = cur.next
cur.next = right
cur = right.next
right = rightNext
cur.next = right
return head