203. 移除链表元素
普通方法没什么好说的,要注意的是对链表进行操作时要注意判断指针空,与数组不同,在对链表进行操作的时候往往不需要只通过单一变量名称进行更改,比如要想改数组的某个元素的时候,a[0] = 10,改链表的时候,只需要改变当前指针所包含的变量和指针即可。
/**
* 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) {
while(head != NULL && head -> val == val)
{
ListNode * p = head;
head = head -> next;
delete p;
}
ListNode * abs = head;
while(abs != NULL && abs -> next != NULL)
{
if(abs->next -> val == val)
{
ListNode * p = abs -> next;
abs -> next = abs -> next -> next;
delete p;
}
else
abs = abs -> next;
}
return 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) {
ListNode * vir_head = new ListNode(0);
vir_head -> val = val +1;
vir_head -> next = head;
ListNode * p = vir_head;
while(p -> next != NULL)
{
if(p -> next -> val == val)
{
p -> next = p -> next -> next;
}
else
{
p = p -> next;
}
}
return vir_head -> next;
}
};
个人感觉虚拟头节点只是一个思路,除了链表是否有其他地方能用到呢?本质就是将头节点归为普通节点了
707. 设计链表
class MyLinkedList {
public:
struct linkedList
{
int val;
linkedList * next;
linkedList(int val):val(val), next(nullptr){};
};
MyLinkedList() {
dummyHead = new linkedList(0);
len = 0;
}
int get(int index) {
if(index > (len-1) || index < 0)
{
return -1;
}
else
{
linkedList *p = dummyHead;
for (int i = 0; i<= index; i++)
{
p = p -> next;
}
return (p -> val);
}
}
void addAtHead(int val) {
linkedList *p = new linkedList(val);
p -> next = dummyHead -> next;
dummyHead -> next = p;
len++;
}
void addAtTail(int val) {
linkedList *p = new linkedList(val);
linkedList *cur = dummyHead;
while(cur -> next != NULL)
{
cur = cur -> next;
}
cur -> next = p;
len++;
}
void addAtIndex(int index, int val) {
if(index > len || index < 0)
{
return ;
}
else
{
linkedList *p = dummyHead ;
linkedList *n = new linkedList(val);
for (int i = 0; i< index; i++)
{
p = p -> next;
}
n -> next = p -> next;
p -> next = n;
len++;
}
}
void deleteAtIndex(int index) {
if(index >= len || index < 0)
{
return ;
}
else
{
linkedList *p = dummyHead ;
for (int i = 0; i< index; i++)
{
p = p -> next;
}
p -> next = (p -> next) -> next;
len--;
}
}
private:
int len;
linkedList* dummyHead;
};
/**
* 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);
*
看着很简单,但是实际写的时候有很多错误,要注意两点:1.有了头节点长度都顺延加一,2.判断截至条件要想好,是大于等于还是大于,有没有+1-1,起始是赋值为头节点还是头节点的next
206. 反转链表
/**
* 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) {
ListNode* pre = NULL;
ListNode* cur = head;
while(cur)
{
ListNode* temp = cur->next;
cur -> next = pre;
pre = cur;
cur = temp;
}
return pre;
}
};
又是一个双指针的例子,目前用到的双指针都是那种如果其中一个变了,另一个也会变的
/**
* 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) {}
* };
*/
ListNode* reverse(ListNode* pre, ListNode* cur)
{
if(!cur)
{
return pre;
}
ListNode* temp = cur -> next;
cur -> next = pre;
return reverse(cur, temp );
}
class Solution {
public:
ListNode* reverseList(ListNode* head) {
return reverse(NULL, head);
}
};
递归快忘光了,19行相当于
其实要想得到结果,必须像剥洋葱一样一层一层剥到底,其终止条件所返回的就是最终结果