203.移除链表元素
Python
直接删除节点:
# Definition for singly-linked list.
# class ListNode(object):
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution(object):
def removeElements(self, head, val):
"""
:type head: ListNode
:type val: int
:rtype: ListNode
"""
"""直接删除"""
while (head != None and head.val == val):#首先要移除头节点,确保头节点不为空,否则会报错,头节点的值==值
head = head.next
# 如果不是头节点,将头节点赋给指针,让指针去遍历移动
cur = head
while (cur != None and cur.next != None):
if (cur.next.val == val):#注意是 值==值,not 指针
cur.next = cur.next.next
else:
cur = cur.next
return head
虚拟头节点:只用这一种即可
# Definition for singly-linked list.
# class ListNode(object):
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution(object):
def removeElements(self, head, val):
"""
:type head: ListNode
:type val: int
:rtype: ListNode
"""
"""虚拟头节点"""
dummyhead = ListNode(next = head)#创建虚拟头节点
cur = dummyhead
while cur.next:#写成dummyhead.next报错 因为下文一直用的是cur指针,操作空指针会报错
if cur.next.val == val:#注意,此处是.val
cur.next = cur.next.next
else:
cur = cur.next
return dummyhead.next#要返回head,但是head可能被删除
C++:
直接删除:
/**
* 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* tmp = head;//如果没有tmp,删除节点后head将指向一个已经被删除的节点
head = head->next;
delete tmp;
}
//删除非头节点
ListNode* cur = head;
while (cur != NULL && cur->next != NULL){
if (cur->next->val == val){//注意是cur->next而不是cur
ListNode* tmp = cur->next;//为什么要定义一个指针
cur->next = cur->next->next;
delete tmp;}
else{
cur = cur->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* dummyhead = new ListNode(0);//
dummyhead->next = head;
//删除节点
ListNode* cur = dummyhead;
while (cur->next != NULL){
if (cur->next->val == val){
ListNode* tmp = cur->next;
cur->next = cur->next->next;
delete tmp;
}else{
cur = cur->next;
}
}
head = dummyhead->next;
delete dummyhead;
return head;
}
};
707.设计链表
题意:
在链表类中实现这些功能:
- get(index):获取链表中第 index 个节点的值。如果索引无效,则返回-1。
- addAtHead(val):在链表的第一个元素之前添加一个值为 val 的节点。插入后,新节点将成为链表的第一个节点。
- addAtTail(val):将值为 val 的节点追加到链表的最后一个元素。
- addAtIndex(index,val):在链表中的第 index 个节点之前添加值为 val 的节点。如果 index 等于链表的长度,则该节点将附加到链表的末尾。如果 index 大于链表长度,则不会插入节点。如果index小于0,则在头部插入节点。
- deleteAtIndex(index):如果索引 index 有效,则删除链表中的第 index 个节点。
python3
class ListNode:
def __init__(self, val=0, next=None):
self.val = val
self.next = next
class MyLinkedList:
def __init__(self):
self.dummy_head = ListNode()
self.size = 0
def get(self, index: int) -> int:
""" 获取链表中下标为 index 的节点的值。如果下标无效,则返回 -1 。"""
# 如果index无效,则返回1,判断在范围之外
if index < 0 or index >= self.size:#[0,size-1]
return -1
#在范围内,定义指针
current = self.dummy_head.next #要返回当前节点的值,cur直接放到head即可
#遍历下标内所有
for i in range(index):
current = current.next
return current.val
def addAtHead(self, val: int) -> None:
"""将一个值为 val 的节点插入到链表中第一个元素之前。
在插入完成后,新节点会成为链表的第一个节点。"""
# 直接在dummy_head后面加一个dumm_head.next即可
self.dummy_head.next = ListNode(val, self.dummy_head.next)#直接在虚你头后面接一个节点
self.size += 1
def addAtTail(self, val: int) -> None:
""" 将一个值为 val 的节点追加到链表中作为链表的最后一个元素。"""
# 定义指针
current = self.dummy_head
while current.next:#遍历,当下一个节点不是NULL,一直向下走,直到最后一个
current = current.next
current.next = ListNode(val)
self.size += 1
def addAtIndex(self, index: int, val: int) -> None:
"""将一个值为 val 的节点插入到链表中下标为 index 的节点之前。
如果 index 等于链表的长度,那么该节点会被追加到链表的末尾。
如果 index 比长度更大,该节点将 不会插入 到链表中。"""
if index < 0 or index >= self.size:
return
current = self.dummy_head
for i in range(index):
current = current.next
current.next = ListNode(val,current.next)
self.size += 1
def deleteAtIndex(self, index: int) -> None:
"""如果下标有效,则删除链表中下标为 index 的节点。"""
if index < 0 or index >= self.size:
return
current = self.dummy_head
for i in range(index):
current = current.next
current.next = current.next.next
self.size -= 1
# Your MyLinkedList object will be instantiated and called as such:
# obj = MyLinkedList()
# param_1 = obj.get(index)
# obj.addAtHead(val)
# obj.addAtTail(val)
# obj.addAtIndex(index,val)
# obj.deleteAtIndex(index)
c++
class MyLinkedList {
public:
struct LinkedNode{
int val;
LinkedNode* next;
LinkedNode(int val):val(val), next(nullptr){}
};
//初始化链表
MyLinkedList() {
_dummyHead = new LinkedNode(0);
_size = 0;
}
//获取链表中下标为 index 的节点的值。如果下标无效,则返回 -1 。
int get(int index) {
if (index < 0 || index >(_size - 1)){
return -1;
}
LinkedNode* cur = _dummyHead->next;//将指针指向要返回的head
while (index){
cur = cur->next;
index--;
}
return cur->val;
}
//将一个值为 val 的节点插入到链表中第一个元素之前。在插入完成后,新节点会成为链表的第一个节点。
void addAtHead(int val) {
LinkedNode* newNode =new LinkedNode(val);
newNode->next = _dummyHead->next;//!!!先将原本head的值赋给插入的节点,否则就找不见了
_dummyHead->next = newNode;
_size++;
}
//将一个值为 val 的节点追加到链表中作为链表的最后一个元素。
void addAtTail(int val) {
LinkedNode* newNode =new LinkedNode(val);
LinkedNode* cur = _dummyHead;
while (cur->next != nullptr){
cur = cur->next;
}
cur->next = newNode;
_size++;
}
// 将一个值为 val 的节点插入到链表中下标为 index 的节点之前。如果 index 等于链表的长度,那么该节点会被追加到链表的末尾。如果 index 比长度更大,该节点将 不会插入 到链表中。
void addAtIndex(int index, int val) {
if (index > _size) return;//注意范围
if (index < 0) index = 0;//??
LinkedNode* newNode = new LinkedNode(val);
LinkedNode* cur = _dummyHead;
while (index){
cur = cur->next;
index--;
}
newNode->next = cur->next;
cur->next = newNode;
_size++;
}
//如果下标有效,则删除链表中下标为 index 的节点。
void deleteAtIndex(int index) {
if (index < 0 || index >=_size){//??
return;
}
LinkedNode* cur = _dummyHead;
while (index){
cur = cur->next;
index--;
}
LinkedNode* tmp = cur->next;
cur->next = cur->next->next;
delete tmp;;
tmp = nullptr;
_size--;
}
// 打印链表
void printLinkedList() {
LinkedNode* cur = _dummyHead;
while (cur->next != nullptr) {
cout << cur->next->val << " ";
cur = cur->next;
}
cout << endl;
}
private:
int _size;
LinkedNode* _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);
*/
206.反转链表
题意:反转一个单链表。
示例: 输入: 1->2->3->4->5->NULL 输出: 5->4->3->2->1->NULL+
方法一:双指针法
pyhton3
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]:
"""双指针法"""
cur = head
pre = None
while cur:
tmp = cur.next
cur.next = pre
pre = cur
cur = tmp
return pre
C++
/**
* 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* temp;
ListNode* cur = head;
ListNode* pre = NULL;
while(cur){
temp = cur->next;
cur->next = pre;
pre = cur;
cur = temp;
}
return pre;
}
};
方法二:递归法
python3
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]:
"""双指针基础上的递归法"""
return self.reverse(head, None)
def reverse(self, cur, pre):
if cur == None:
return pre
tmp = cur.next
cur.next = pre
return self.reverse(tmp, cur)
c++
/**
* 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) {
return reverse(NULL, head);
}
ListNode* reverse(ListNode* pre,ListNode* cur){
if (cur == NULL) return pre;
ListNode* temp = cur->next;
cur->next = pre;
return reverse(cur, temp);
}
};