链表问题
1、给定一个单链表,把所有的奇数节点和偶数节点分别排在一起。请注意,这里的奇数节点和偶数节点指的是节点编号的奇偶性,而不是节点的值的奇偶性。
请尝试使用原地算法完成。你的算法的空间复杂度应为 O(1),时间复杂度应为 O(nodes),nodes 为节点总数。
请尝试使用原地算法完成。你的算法的空间复杂度应为 O(1),时间复杂度应为 O(nodes),nodes 为节点总数。
一定要考虑head节点是否为空,不然定义指针指向head->next会报错
示例: 输入: 1->2->3->4->5->NULL 输出: 1->3->5->2->4->NULL
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* oddEvenList(ListNode* head) {
ListNode *pre,*cur;
if(!head || !head->next)
return head;
pre = head;
cur = head->next;
while(cur && cur->next){
ListNode *tmp = pre->next;
pre->next = cur->next;
cur->next = cur->next->next;
pre->next->next = tmp;
pre = pre->next;
cur = cur->next;
}
return head;
}
}; 2、删除链表中等于给定值 val 的所有节点。 考虑到第一个节点也可能被删除,所以要设置一个虚拟的头结点,令其指向head
示例: 输入: 1->2->6->3->4->5->6, val = 6 输出: 1->2->3->4->5
class Solution {
public:
ListNode* removeElements(ListNode* head, int val) {
ListNode *cur;
ListNode *h = new ListNode(-1);
h->next = head;
cur = h;
while(cur->next){
if(cur->next->val == val){
cur->next = cur->next->next;
}else{
cur = cur->next;
}
}
return h->next;
}
};
3、Given a linked list, swap every two adjacent nodes and return its head.You may not modify the values in the list's nodes, only nodes itself may be changed.
(交换相邻结点,一定要注意设置虚拟头结点)
Example: Given1->2->3->4, you should return the list as2->1->4->3.
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* swapPairs(ListNode* head) {
if(!head || !head->next)
return head;
ListNode *preHead = new ListNode(0);
preHead->next = head;
ListNode *p = preHead;
while(p->next&&p->next->next){
ListNode *node1 = p->next;
ListNode *node2 = node1->next;
ListNode *next = node2->next;
node1->next = next;
node2->next = node1;
p->next = node2;
p = node1;
}
return preHead->next;
}
}; 4、请编写一个函数,使其可以删除某个链表中给定的(非末尾)节点,你将只被给定要求被删除的节点。 示例:
输入: head = [4,5,1,9], node = 5
输出: [4,1,9]
解释: 给定你链表中值为 5 的第二个节点,那么在调用了你的函数之后,该链表应变为 4 -> 1 -> 9.
输出: [4,1,9]
解释: 给定你链表中值为 5 的第二个节点,那么在调用了你的函数之后,该链表应变为 4 -> 1 -> 9.
【通过将待删除节点后面的值赋给待删除节点,然后将其后的节点删除】
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
void deleteNode(ListNode* node) {
ListNode *t = node->next;
node->val = node->next->val;
node->next = node->next->next;
delete t;
}
}; 5、使用快慢指针找到链表的中心点,用栈进行存储 请判断一个链表是否为回文链表。
示例 1:
输入: 1->2 输出: false
示例 2:
输入: 1->2->2->1 输出: true进阶:
你能否用 O(n) 时间复杂度和 O(1) 空间复杂度解决此题?
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
bool isPalindrome(ListNode* head)
{
if(head==NULL||head->next==NULL) //特殊处理
return true;
ListNode *fast=head;
ListNode *slow=head;
ListNode *left=head;
stack<int>s;
s.push(head->val); //利用快慢指针法让slow找到中心点
while(fast->next&&fast->next->next)
{
fast=fast->next->next;
slow=slow->next;
s.push(slow->val);
}
if(fast->next==NULL) //奇数链做退栈处理,保证栈里面和slow的右边对称
s.pop();
while(!s.empty())
{
if(s.top()!=slow->next->val)
{
return false;
}
else
{
slow=slow->next;
s.pop();
}
}
return true;
}
};

京公网安备 11010502036488号