Autumn Recruitment Warfare - Algorithms Series (Link Table Topics) Updating....

The autumn recruitment in 2019 has begun one after another. Here, I record some algorithm questions in the process of preparing for the recruitment. The main sources of the topics are offer ing by sword and leetcode:

Basic questions:

Enter a linked list and return an ArrayList in the end-to-end order of the linked list values.

Ideas:
s1: Traverse the list from beginning to end and store the value of each node in the stack
s2: Exit elements from the stack

/**
*  struct ListNode {
*        int val;
*        struct ListNode *next;
*        ListNode(int x) :
*              val(x), next(NULL) {
*        }
*  };
*/
class Solution {
public:
    vector<int> printListFromTailToHead(ListNode* head) {
        vector<int> res;
        stack<int> array;
        ListNode* node = head;
        int temp;
        while(node != NULL){
            array.push(node->val);
            node = node->next;
        }
        while(!array.empty()){
            temp = array.top();
            res.push_back(temp);
            array.pop();
        }
        return res;
    }
};

Advanced questions:

Input a list and output the reciprocal k node in the list.

Ideas:
Violent solution:
s1: Traverse the list from beginning to end, statistic the number of nodes in the list is n
s2: Find the reciprocal K node, and the reciprocal K node is the n-k+1 node starting from the initial node.
Optimal Solution (Double Pointer)
s1: First move the first pointer p1 backwards to the k-th node
s2: Put the second pointer p2 at the first node
s3: The two nodes are traversed backwards at the same time. When p1 reaches the end of the list, the position of p2 is the reciprocal k node.

/*
struct ListNode {
	int val;
	struct ListNode *next;
	ListNode(int x) :
			val(x), next(NULL) {
	}
};*/
class Solution {
public:
    ListNode* FindKthToTail(ListNode* pListHead, unsigned int k) {
        if(pListHead == NULL){
            return pListHead;
        }
        ListNode* p1 = pListHead;
        ListNode* p2 = pListHead;
        for(int i = 0; i < k-1; i++){
            if(p1->next != NULL){
                p1 = p1->next;
            }else{
                return p1->next;
            }
        }
        while(p1->next != NULL){
            p1 = p1->next;
            p2 = p2->next;
        }
        return p2;
    }
};

Input a list, invert the list, and output the header of the new list.

This question mainly examines pointer reversal.
Ideas:

/*
struct ListNode {
	int val;
	struct ListNode *next;
	ListNode(int x) :
			val(x), next(NULL) {
	}
};*/
class Solution {
public:
    ListNode* ReverseList(ListNode* pHead) {
        if(pHead == NULL){
            return NULL;
        }
        ListNode* pNode = pHead;
        ListNode* pre = NULL;
        ListNode* pReverseHead = NULL;
        while(pNode != NULL){
            ListNode* pNext = pNode->next;
            if(pNode->next == NULL){
               pReverseHead = pNode;
            }
             pNode->next = pre;
             pre = pNode;
             pNode = pNext;
        }
        return pReverseHead;
    }
};

Input two monotonically increasing linked lists, output two combined linked lists, of course, we need to synthesize the linked list to meet the monotonic rule.

Recursive thinking is the main way to solve this problem.
s1: traverse two linked lists from the ab initio node
s2: Assign the smallest value of the two nodes to the current node, and continue to compare the next node containing the small node list with the current node of the other list.
s3: Repeat s2 until the current node of both lists is empty

/*
struct ListNode {
	int val;
	struct ListNode *next;
	ListNode(int x) :
			val(x), next(NULL) {
	}
};*/
class Solution {
public:
    ListNode* Merge(ListNode* pHead1, ListNode* pHead2)
    {
        //When a list traversal ends, point to another list
        if(pHead1 == NULL){
            return pHead2;
        }
        else if(pHead2 == NULL){
            return pHead1;
        }
        ListNode* curNode = NULL;
        if(pHead1->val < pHead2->val){
            curNode = pHead1;
            curNode->next = Merge(pHead1->next, pHead2);
        }else{
            curNode = pHead2;
            curNode->next = Merge(pHead1, pHead2->next);
        }
        return curNode;
    }
};

Enter two linked lists to find their first common node.

Ideas:
By definition, the title is two single linked lists, so there is no bifurcation after the nodes overlap, as follows:

Because the length of two linked lists may be inconsistent, the length of the linked list can be obtained before traversing the two linked lists. For example, a long list is one element longer than a short list. First, a long list node will be traversed, and then at the same time. The idea of solving the problem is as follows:
s1: Get two list lengths
s2: The long list is traversed beyond the part, and when the number of remaining nodes is the same as that of the short list, the traversal begins at the same time.
s3: Stop traversal when the nodes of two linked lists are equal

/*
struct ListNode {
	int val;
	struct ListNode *next;
	ListNode(int x) :
			val(x), next(NULL) {
	}
};*/
class Solution {
public:
    int getLength(ListNode* pHead){
        ListNode* pNode = pHead;
        int length = 0;
        while(pNode != NULL){
            pNode = pNode->next;
            ++length;
        }
        return length;
    }
    ListNode* FindFirstCommonNode( ListNode* pHead1, ListNode* pHead2) {
        int length1 = getLength(pHead1);
        int length2 = getLength(pHead2);
        
        ListNode* pNode1 = pHead1;
        ListNode* pNode2 = pHead2;
        
        if(length1 >= length2){
            int dif = length1-length2;
            for(int i = 0; i < dif; i++){
                pNode1 = pNode1->next;
            }
        }
        if(length1 < length2){
            int dif = length2-length1;
            for(int i = 0; i < dif; i++){
                pNode2 = pNode2->next;
            }
        }
        while((pNode1 != NULL) && (pNode2 != NULL) && (pNode1 != pNode2)){
            pNode1 = pNode1->next;
            pNode2 = pNode2->next;
        }
        
        return pNode1;
    }
};

Get up to the top of the question

Enter a complex linked list (each node has a node value and two pointers, one pointing to the next node, and the other pointing to any node), and return the result as the head of the replicated complex linked list. (Note that in the output, do not return the node reference in the parameter, otherwise the judgement program will return to null directly)

On this issue, it can be divided into three steps:
s1: Copy each node of the original list and connect it with next
s2: Copy random pointers for each node
s3: Split the original list and duplicate the list

/*
struct RandomListNode {
    int label;
    struct RandomListNode *next, *random;
    RandomListNode(int x) :
            label(x), next(NULL), random(NULL) {
    }
};
*/
class Solution {
public:
    void NodeClone(RandomListNode* pHead){
        RandomListNode* pNode = pHead;
        while(pNode != NULL){
            RandomListNode* pCloned = new RandomListNode(pNode->label);
            
            pCloned->label = pNode->label;
            pCloned->next = pNode->next;
            pCloned->random = NULL; 
            
            pNode->next = pCloned;
            pNode=pCloned->next;
        }
    }
    
    void NodeRandom(RandomListNode* pHead){
        RandomListNode* pNode = pHead;
        while(pNode != NULL){
            RandomListNode* pCloned = pNode->next;
            if(pNode->random != NULL){
                pCloned->random = pNode->random->next;
            }
            pNode = pCloned->next;
        }
    }
    
    RandomListNode* NodeDisConnnect(RandomListNode* pHead){
        RandomListNode* pNode = pHead;
        RandomListNode* pClonedHead = NULL;
        RandomListNode* pCloned = NULL;
        
        if(pNode != NULL){
            pClonedHead = pCloned = pNode -> next;
            pNode->next = pCloned->next;
            pNode = pNode->next;
        }
        while(pNode != NULL){
            pCloned->next = pNode->next;
            pCloned = pCloned->next;
            pNode->next = pCloned->next;;
            pNode = pNode->next;
        }
        return pClonedHead;
    }
    
    RandomListNode* Clone(RandomListNode* pHead)
    {
        if(pHead == NULL){
            return pHead;
        }
        NodeClone(pHead);
        NodeRandom(pHead);
        return NodeDisConnnect(pHead);
    }
};

Posted by pyro3k on Tue, 30 Jul 2019 23:26:14 -0700