移除链表元素
题目描述:给定一个链表的头节点 head 和一个整数 val,让删除链表中所有满足 Node->val == val 的节点,并返回新的头结点。
思路
删除链表结点: p->next = p->next->next 其中 p->next 的值等于val
从前到后依次遍历每个节点,若值等于val,删除即可。
代码
1.迭代
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
ListNode* removeElements(ListNode* head, int val) {
ListNode* dummyNode = new ListNode(-1, head);
ListNode* p = dummyNode;
while (p->next != NULL)
{
ListNode* item = p->next;
if (item->val == val)
{
p->next = item->next;
delete item;
}
else
p = item;
}
return dummyNode->next;
}
};
3.递归
相当于从后往前依次处理节点
模版:
void fun(LinkNode* head)
{
if (head == NULL)
return head;
// 前序遍历
fun(head->next);
// 后序遍历
}
对head的操作相当于对所有链表上其他节点的操作
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
ListNode* removeElements(ListNode* head, int val) {
if (head == NULL)
return head;
head->next = removeElements(head->next, val);
if (head->val != val)
return head;
else
return head->next;
}
};
设计链表
题目描述:设计一个链表类,实现 get(index), addAtHead(val), addAtTail(val), addAtIndex(index, val), deleteAtIndex(index)这些功能。
思路
代码
class MyLinkedList {
struct Node
{
int val;
Node* next;
Node(int val) : val(val), next(NULL) {};
Node(int val, Node* next)
{
val = val;
next = next;
}
};
private:
int _size; // 链表长度
Node* _dummyNode; // 头节点
public:
MyLinkedList() {
_size = 0;
_dummyNode = new Node(-1);
}
int get(int index) {
if (index < 0 || index >= _size)
return -1;
Node* p = _dummyNode;
for (int i = 0; i < index; i++)
p = p->next;
return p->next->val;
}
void addAtHead(int val) {
Node* item = new Node(val);
item->next = _dummyNode->next;
_dummyNode->next = item;
_size++;
}
void addAtTail(int val) {
Node* item = new Node(val);
Node* p = _dummyNode;
while (p->next != NULL)
p = p->next;
p->next = item;
_size++;
}
void addAtIndex(int index, int val) {
if (index < 0 || index > _size)
return;
Node* item = new Node(val);
Node* p = _dummyNode;
for (int i = 0; i < index; i++)
p = p->next;
item->next = p->next;
p->next = item;
_size++;
}
void deleteAtIndex(int index) {
if (index < 0 || index >= _size)
return;
Node* p = _dummyNode;
for (int i = 0; i < index; i++)
p = p->next;
Node* item = p->next;
p->next = item->next;
delete item;
_size--;
}
};
/**
* Your MyLinkedList object will be instantiated and called as such:
* MyLinkedList* obj = new MyLinkedList();
* int param_1 = obj->get(index);
* obj->addAtHead(val);
* obj->addAtTail(val);
* obj->addAtIndex(index,val);
* obj->deleteAtIndex(index);
*/
反转链表
题目思路:给定单链表的头结点 head,反转链表,并返回反转后的链表。
思路
首先创建一个带头节点的空链表,从前到后遍历原单链表,将该链表上的节点通过头插法插入空链表。
代码
1.迭代
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
ListNode* reverseList(ListNode* head) {
if (head == NULL || head->next == NULL)
return head;
ListNode* dummyNode = new ListNode(-1);
ListNode* p = head;
ListNode* item;
while (p->next != NULL)
{
item = p->next;
p->next = dummyNode->next;
dummyNode->next = p;
p = item;
}
// for last Node
p->next = dummyNode->next;
dummyNode->next = p;
return dummyNode->next;
}
};
2.递归
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
ListNode* reverseList(ListNode* head) {
if (head == NULL || head->next == NULL) // only one Node
return head;
ListNode* newHead = reverseList(head->next);
ListNode* p = newHead;
if (p != NULL)
{
while (p->next != NULL)
p = p->next;
}
p->next = head;
head->next = NULL;
return newHead;
}
};
下面这种比较巧妙,利用原节点head->next是head->next子链表的最后一个节点,从而不用遍历子链表即可把head连接在子链表的最后,从而反转整个链表。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
ListNode* reverseList(ListNode* head) {
if (head == NULL || head->next == NULL) // only one Node
return head;
ListNode* newHead = reverseList(head->next);
head->next->next = head; // head->next 原链表的第二个节点
head->next = NULL;
return newHead;
}
};