目录
移除链表元素
题目链接:
特点/解法概述:
通过一个指针遍历链表,如果所指节点的值等于 要删除的 值,则删除这个节点。
细节/手法:
1.头节点移除问题,因为移除的步骤是 找到移除节点的前一个节点,然后把节点的前一个节点 删除, 而头节点没有前一个节点,需要做特殊节点,或者虚拟出一个节点,由这个节点做头节点。
2.如果每次都cur= cur->next; 就会漏掉连续等于目标值的情况。
3.使用原链表删除元素,记得用临时指针来遍历,就不需要改变 head. 这样return 的时候就可以 return head
4.使用虚拟头节点的时候,需要返回的是 虚拟头节点的下一个节点,因为 有可能 形式参数传入 的head 已被删除。
语言知识:
题解:
class Solution {
public:
ListNode* removeElements(ListNode* head, int val) {
ListNode * virtualHead1 = new ListNode(0,head);
ListNode * virtualHead = virtualHead1;
while(virtualHead)
{
if(virtualHead->next && virtualHead->next->val == val) //出现的问题1 要先判断指针是否为空,再判断指针的值,才可以避免空指针错误
{
ListNode *temp=virtualHead->next;
virtualHead->next=virtualHead->next->next;
delete temp;
}
else
{
virtualHead=virtualHead->next; //出现的问题2 如果每次都next 就会漏掉连续等于目标值的情况。
}
}
//出现的问题3 使用虚拟头节点的时候,需要返回的是 虚拟头节点的下一个节点,因为 有可能 形式参数传入 的head 已被删除
return virtualHead1->next;
}
};
设计链表
链接:
细节/手法:
1.获取第n个节点的值
要注意边界问题,即如果是空节点就 不用执行遍历的操作。
2.头部插入节点
要先将 新的节点的next指向 原来的第一个节点
然后 再将头节点的next 指向 新的节点
这样就不会出现 头节点的next指向 新节点后,新节点 获取不到 原来第一个节点的情况。
不要忘记size ++
3.尾部插入节点
明确出口条件为 xx->next 不为空
4.第n个节点前插入节点
明确遍历完成 后 cur 是 n 的前一个节点,这样才能执行操作
不要忘记size ++
5.删除第n个节点
第n个节点一定是 cur->next;
我们操作cur 来删除cur 这个节点
不要忘记size --
语言知识/编程思想:
1.对于边界值的处理,带入边界值 进行模拟。
2.构造函数使用初始化列表:
struct LinkedNode {
int val;
LinkedNode* next;
LinkedNode(int val):val(val), next(nullptr){}
};
题解:
class MyLinkedList {
typedef struct Node
{
int value;
Node * next;
Node(int val):value(val),next(nullptr)
{
}
}Node;
public:
MyLinkedList() {
_virtualHead = new Node(0);
_size =0;
}
int get(int index) {
if (index > (_size - 1) || index < 0) {
return -1;
}
Node * cur=_virtualHead->next;
while(index-- )
{
cur=cur->next;
}
return cur->value;
}
void addAtHead(int val) {
Node *new_node = new Node(val);
new_node->next = _virtualHead->next;
_virtualHead->next=new_node;
_size++;
}
void addAtTail(int val) {
Node * new_node = new Node(val);
Node *cur = _virtualHead;
while(cur->next !=nullptr)
{
cur = cur->next;
}
cur->next = new_node;
_size++;
}
void addAtIndex(int index, int val) {
if(index>_size)
{
return;
}
if (index < 0) {
index = 0;
}
Node * new_node = new Node(val);
Node *cur = _virtualHead; //注意这里指向的是虚拟头结点
while(index--)
{
cur=cur->next;
}
//指向index的前一个节点
new_node->next = cur->next;
cur->next=new_node;
_size++;
}
void deleteAtIndex(int index) {
if (index >= _size || index < 0) {
return;
}
Node *cur = _virtualHead; //注意这里指向的是虚拟头结点
while(index--)
{
cur=cur->next;
}
Node *temp;
temp = cur->next;
cur->next = cur->next->next;
delete temp;
_size--;
}
private:
int _size;
Node *_virtualHead;
};
/**
* 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);
*/
翻转链表
链接:
题解:
class Solution {
public:
ListNode* reverseList(ListNode* head) {
//定义一个指向前一个节点的指针和 指向当前节点的指针
ListNode *pre =NULL; //关键
ListNode *cur = head;
ListNode *temp;
while(cur)
{
temp=cur->next;
cur->next =pre;
pre=cur;
cur=temp;
}
return pre;
}
};