Leetcode(203. Remove Linked List Elements&707. Design Linked List&206. Reverse Linked List)

Journey of LeetCode|DAY 3

  • Preface
  • 1.Remove Linked List Elements
    • Analysis and Solution
      • Direct Delete
      • Dummy Head Node
  • 2.Design Linked List
    • Analysis and Solution
      • Dummy Head Node
  • 3.Reverse Linked List
    • Analysis and Solution
      • double pointer
      • Recursion
  • Conclusion

Preface

This is a new day to start my LinkedList journey.
Learn something new and keep reviewing what I learnt before.

1.Remove Linked List Elements

LeetCode Link: 203.Remove Linked List Elements
Given the head of a linked list and an integer val, remove all the nodes of the linked list that has Node.val == val, and return the new head.

Analysis and Solution

Direct Delete

Direct Delete divides the two situations that one is to delete the head node; the other is to delete not head node.

Delete head node:
just move the head pointer
head = head->next;//move head pointer
then free memory

Delete not head node:
cur->next = cur->next->next;//change the object of the pointer
then free memory

LeetCode C++ as followings Direct Delete

/**
 * 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) {
          // Delete head node
        while (head != NULL && head->val == val) { // to continue the process,use while instead of if
            ListNode* tmp = head;//define a temporary pointer 
            head = head->next;//move head pointer
            delete tmp;//Delete head node
        }

        // Delete not head node
        ListNode* cur = head;//define a current pointer
        while (cur != NULL && cur->next!= NULL) {//same as before
            if (cur->next->val == val) {//find the target
                ListNode* tmp = cur->next;//define a temporary pointer
                cur->next = cur->next->next;//change the object of the pointer
                delete tmp;//Delete not head node
            } else {
                cur = cur->next;//move the pointer to next one to find the target
            }
        }
        return head;

    }
};

Dummy Head Node

To unify the two situations that can be solved by the same code. Define a new dummy node to delete the head node and not head node.

if(cur->next->val == val) {//find the target
ListNode* tmp = cur->next;//define a temporary pointer
cur->next = cur->next->next;//change the object of the pointer

LeetCode C++ as followings Dummy Head Node

/**
 * 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); // define a new dummy node
        dummyHead->next = head; // dummy node points the head node
        ListNode* cur = dummyHead;//define a current pointer
        while (cur->next != NULL) {//to continue the process,use while instead of if
            if(cur->next->val == val) {//find the target
                ListNode* tmp = cur->next;//define a temporary pointer
                cur->next = cur->next->next;//change the object of the pointer
                delete tmp;//free memory
            } else {
                cur = cur->next;//move the pointer and continue the process
            }
        }
        head = dummyHead->next;//move the pointer
        delete dummyHead;//delete a pointer
        return head;//reture the new linkedlist

    }
};

2.Design Linked List

LeetCode Link: 707.Design Linked List
Design your implementation of the linked list. You can choose to use a singly or doubly linked list.
A node in a singly linked list should have two attributes: val and next. val is the value of the current node, and next is a pointer/reference to the next node.
If you want to use the doubly linked list, you will need one more attribute prev to indicate the previous node in the linked list. Assume all nodes in the linked list are 0-indexed.

Implement the MyLinkedList class:

MyLinkedList() Initializes the MyLinkedList object.
int get(int index) Get the value of the indexth node in the linked list. If the index is invalid, return -1.
void addAtHead(int val) Add a node of value val before the first element of the linked list. After the insertion, the new node will be the first node of the linked list.
void addAtTail(int val) Append a node of value val as the last element of the linked list.
void addAtIndex(int index, int val) Add a node of value val before the indexth node in the linked list. If index equals the length of the linked list, the node will be appended to the end of the linked list. If index is greater than the length, the node will not be inserted.
void deleteAtIndex(int index) Delete the indexth node in the linked list, if the index is valid.

Analysis and Solution

this is a series of easy operation of LinkedList, no more bullshit, just show the code.

Dummy Head Node

To do the CRUD(creat、read、update and delete) that can be solved easier.
Define a new dummy node to do the operation easier.

LeetCode C++ as followings Dummy Head Node

class MyLinkedList {
public: 
struct LinkedNode {//define the structure of the linkedlist node,and initial the function
        int val;
        LinkedNode* next;
        LinkedNode(int val):val(val), next(nullptr){}
    };
    // initial the linkedlist
    MyLinkedList() {
        dummyHead = new LinkedNode(0); // define a dummyhead to do CRUD easier
        size = 0;
    }
    
  int get(int index) {
        if (index > (size - 1) || index < 0) {//define the Boundary conditions
            return -1;
        }
        LinkedNode* cur = dummyHead->next;//define a current pointer
        while(index--){ // traverse the list
            cur = cur->next;
        }
        return cur->val;//return the value if find the target
    }

    // add node at the begining of the list,and it becomes the new headnode after it was done
    void addAtHead(int val) {
        LinkedNode* newNode = new LinkedNode(val);//define a new node
        newNode->next = dummyHead->next;//insert the new node
        dummyHead->next = newNode;
        size++;//size+1
    }

    // add a node in the end of the list
    void addAtTail(int val) {
        LinkedNode* newNode = new LinkedNode(val);//same as before
        LinkedNode* cur = dummyHead;//same as before
        while(cur->next != nullptr){//traverse to find the last one element
            cur = cur->next;
        }
        cur->next = newNode;//link the new node
        size++;//size+1
    }

    // add a new node before indexth node.
    // if index = 0,newNode will be newHeadNode
    // if index = size of list,newNode will be tailnode
    // if index > size of list,return none
    // if index < 0,return none
    void addAtIndex(int index, int val) {
        if (index > size || index < 0) {//if index > size of list or index < 0 ,return none
            return;
        }
        LinkedNode* newNode = new LinkedNode(val);//define a newNode
        LinkedNode* cur = dummyHead;//define a current pointer
        while(index--) {//traverse to fine the target
            cur = cur->next;
        }
        newNode->next = cur->next;//insert the newNode
        cur->next = newNode;
        size++;//size+1
    }

    //delete the indexth node,if index > size of list or index < 0 ,return none
    void deleteAtIndex(int index) {
        if (index >= size || index < 0) {//if index > size of list or index < 0 ,return none
            return;
        }
        LinkedNode* cur = dummyHead;//define a current pointer
        while(index--) {//traverse to find the target
            cur = cur ->next;
        }
        LinkedNode* tmp = cur->next;//define a tempoary pointer to delete a node
        cur->next = cur->next->next;
        delete tmp;
        size--;//size-1
    }

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);
 */

3.Reverse Linked List

LeetCode Link: 206.Reverse Linked List
Given the head of a singly linked list, reverse the list, and return the reversed list.

Analysis and Solution

double pointer

double pointer indicates the current value and pre value.
save the next node in the temporary.
then change the current’s pointer to indicates pre.
move the pre and current pointer to next node.

LeetCode C++ as followings double pointer

/**
 * 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;//define a temporary pointer 
        ListNode* cur = head ;//define a current pointer to indicates headNode 
        ListNode* pre = NULL ;//define a pre pointer to indicates before headNode
        while(cur){//traverse list
            temp = cur->next;//temp saves next node
            cur->next = pre;//current points to pre
            pre = cur;//move pre pointer to current 
            cur = temp;//current pointer moves to next Node
        }
        return pre;//(NUll or current value)
    }
};

Recursion

Recursion same as double pointer in the essence of the code.
LeetCode C++ as followings Recursion

/**
 * 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* reverse(ListNode* pre,ListNode* cur){//a new function 
        if(cur == NULL) return pre;//boundary condition
        ListNode* temp = cur->next;//temp saves the next node
        cur->next = pre;//current points to pre
        return reverse(cur,temp);//essence of recursion. pre = cur; cur = temp;
    }
    ListNode* reverseList(ListNode* head) {
        return reverse(NULL, head);// ListNode* cur = head; ListNode* pre = NULL;
    }
};

Conclusion

Not an easy day.
Recursion should take more time to understand.
Review them later.

你可能感兴趣的:(leetcode,list,c++)