LeetCode203 移除链表元素
给你一个链表的头结点head和一个整数val,请你删除链表中所有满足Node.val == val的节点,并返回新的头结点。
链表不同于数组,数组不能删除元素只能覆盖,链表可以通过释放该节点的内存,实现删除。该题较为简单,可以原地操作,判断每个节点的值即可,也可以通过虚拟头结点的方式操作,建议使用虚拟头结点,更加便利,时间复杂度都为O(n)。
struct ListNode* removeElements(struct ListNode* head, int val){
typedef struct ListNode ListNode;
struct ListNode* dummyhead;
dummyhead = (ListNode*)malloc(sizeof(ListNode));
dummyhead->next = head;
struct ListNode* cur = dummyhead;
while(cur->next){
if(cur->next->val == val){
ListNode* tmp = cur->next;
cur->next = cur->next->next;
free(tmp);
}else{
cur = cur->next;
}
}
return dummyhead->next;
}
LeetCode707 设计链表
要求实现链表操作的相关接口,包括get(index)、addAtHead(val)、addAtTail(val)、addAtIndex(index, val)、deleteAtIndex(index)和free(head),设计链表不难,但是实现起来较为复杂,特别是基于C的实现,在此都借助虚拟头结点操作链表。
链表实现(C,假设有头结点):
typedef struct LNode {
int val;
struct LNode* next;
} MyLinkedList;
MyLinkedList* myLinkedListCreate() {
MyLinkedList* obj = (MyLinkedList*)malloc(sizeof(MyLinkedList));
obj->next = NULL;
return obj;
}
int myLinkedListGet(MyLinkedList* obj, int index) {
MyLinkedList* cur = obj->next;
for (int i = 0; cur != NULL; i++){
if (i == index){
return cur->val;
}else{
cur = cur->next;
}
}
return -1;
}
void myLinkedListAddAtHead(MyLinkedList* obj, int val) {
MyLinkedList* node = (MyLinkedList*)malloc(sizeof(MyLinkedList));
node->val = val;
node->next = obj->next;
obj->next = node;
}
void myLinkedListAddAtTail(MyLinkedList* obj, int val) {
MyLinkedList* node = (MyLinkedList*)malloc(sizeof(MyLinkedList));
node->val = val;
node->next = NULL;
MyLinkedList* cur = obj;
while(cur->next != NULL){
cur = cur->next;
}
cur->next = node;
}
void myLinkedListAddAtIndex(MyLinkedList* obj, int index, int val) {
if(index == 0){
myLinkedListAddAtHead(obj, val);
return;
}
MyLinkedList* cur = obj->next;
for(int i = 1; cur != NULL; i++){
if(i == index){
MyLinkedList* node = (MyLinkedList*)malloc(sizeof(MyLinkedList));
node->val = val;
node->next = cur->next;
cur->next = node;
return;
}else{
cur = cur->next;
}
}
}
void myLinkedListDeleteAtIndex(MyLinkedList* obj, int index) {
if(index == 0){
MyLinkedList* tmp = obj->next;
if(tmp != NULL){
obj->next = tmp->next;
free(tmp);
}
return;
}
MyLinkedList *cur = obj->next;
for (int i = 1; cur != NULL && cur->next != NULL; i++){
if (i == index){
MyLinkedList *tmp = cur->next;
cur->next = tmp->next;
free(tmp);
return;
}else{
cur = cur->next;
}
}
}
void myLinkedListFree(MyLinkedList* obj) {
while(obj != NULL){
MyLinkedList* tmp = obj;
obj = obj->next;
free(tmp);
}
}
链表实现(C++,假设有头结点):
class MyLinkedList {
public:
struct LinkedNode {
int val;
LinkedNode* next;
LinkedNode(int val):val(val),next(nullptr){}
};
MyLinkedList() {
_dummyHead = new LinkedNode(0);
_size = 0;
}
int get(int index) {
if(index > (_size - 1) || index < 0){
return -1;
}
LinkedNode* cur = _dummyHead->next;
while(index--) {
cur = cur->next;
}
return cur->val;
}
void addAtHead(int val) {
LinkedNode* newNode = new LinkedNode(val);
newNode->next = _dummyHead->next;
_dummyHead->next = newNode;
_size++;
}
void addAtTail(int val) {
LinkedNode* newNode = new LinkedNode(val);
LinkedNode* cur = _dummyHead;
while(cur->next != NULL) {
cur = cur->next;
}
cur->next = newNode;
_size++;
}
void addAtIndex(int index, int val) {
if(index > _size || index < 0){
return;
}
LinkedNode* newNode = new LinkedNode(val);
LinkedNode* cur = _dummyHead;
while(index--) {
cur = cur->next;
}
newNode->next = cur->next;
cur->next = newNode;
_size++;
}
void deleteAtIndex(int index) {
if(index > _size || index < 0){
return;
}
LinkedNode* cur = _dummyHead;
while(index--) {
cur = cur->next;
}
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;
};
LeetCode206 反转列表
在不定义新链表的前提下,实现链表元素的反转,借助双指针,依次改变各个元素节点的指向即可,当尾指针指向空时结束。
反转列表(C++,双指针法):
class Solution {
public:
ListNode* reverseList(ListNode* head) {
struct ListNode* cur = head;
struct ListNode* pre = nullptr;
struct ListNode* tmp;
while(cur) {
tmp = cur->next;
cur->next = pre;
pre = cur;
cur = tmp;
}
return pre;
}
};
反转列表(C++,递归法):
class Solution {
public:
ListNode* reverse(struct ListNode* pre, struct ListNode* cur) {
if(!cur) return pre;
struct ListNode* tmp = cur->next;
cur->next = pre;
return reverse(cur, tmp);
}
ListNode* reverseList(ListNode* head) {
return reverse(nullptr, head);
}
};