题目本身难度不到,只想讲一些关于链表的操作。这里看了几篇博客,写得好的使用了一个小技巧
在新链表list的头部多分配了一个节点的空间,从而简化了接下来对于链表的操作,这又什么好处呢?最后返回的的时候,返回list->next就行,然而由于这个新链表具有自己的数据空间因此,就可以在这个新链表上直接操作,省略了通过判断,从而给新链表赋值的过程,简化了操作,这个确实是个很好的小技巧。
思路:我首先的思路是通过两个vector<listNode*> less,great,如果比较的结果小,就放入less,否则放入great,最后从less开始,依次取出vector里面的元素,然后将它们连在一起、很显然,一是耗用的内存更多了,二是多了很多的判断,比如要判断less是否为空,同时如何将less最后一个节点和great第一个节点相连,很显然,多了很多判断及要考虑的情况。按这种思路写一遍就知道了。
而采用技巧的话,通过一个标记flag和一个游标cur,flag指向新链表当前最后一个元素,cur则寻找链表中比参数小的元素,没发现一个就把它flag之后,同时flag后移(Point:注意这里的指针连接操作,建议手写一遍理一下),这样好处很明显,首先由于新链表有自己的空间(其实新链表就只分配了头结点的空间),那么一开始也不用判断头节点到底应该是从哪里开始,可以一开始就开始对原来链表的处理工作;第二个就是后续的操作在原来链表上进行就可以,在内部调整顺序。
问题描述:
给定一个单链表和数值x,划分链表使得所有小于x的节点排在大于等于x的节点之前。
你应该保留两部分内链表节点原有的相对顺序。
样例
给定链表 1->4->3->2->5->2->null,并且 x=3
返回 1->2->2->4->3->5->null
代码:
class Solution {
public:
/*
* @param head: The first node of linked list
* @param x: An integer
* @return: A ListNode
*/
ListNode * partition(ListNode * head, int x) {
// write your code here
if(nullptr == head) return head;
ListNode *front = new ListNode(0);
front->next = head;
ListNode *pre, *cur; //运用游标,给链表加个头
pre = front;
while(pre->next && pre->next->val < x) pre = pre->next;
cur = pre;
while(nullptr != cur->next)
{
ListNode *tmp;
if(cur->next->val < x)
{
tmp = cur->next;
cur->next = tmp->next;
tmp->next = pre->next;
pre->next = tmp;
pre = tmp;
}
else
{
cur = cur->next;
}
}
return front->next;
}
};
PS:注意编码的细节以及效率,以较少的提交次数通过
参考链接:点击打开链接