# Algorithm training phase 2 – linked list

Time：2021-2-10

#### Sword finger offer 24

Example:

``````Input: 1 - > 2 - > 3 - > 4 - > 5 - > null
Output: 5 - > 4 - > 3 - > 2 - > 1 - > null``````

Restrictions:

``0 < = number of nodes < = 5000``

Idea 1:

Although it is the practice of linked list, there are many ideas of algorithm. As I said before, all kinds of methods will be used, not the linked list part, only the linked list

This topic: need to return a list pointer, this is a new list. This new list essentially takes elements one by one from the end of the old list. That is to say, for the old linked list, it is actually a case of first in and last out. So the first thing we think of is the stack.

Press the stack from the beginning, and then one by one out of the stack. Put it into a new linked list;

``````/**
* struct ListNode {
*     int val;
*     ListNode *next;
*     ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
stack<ListNode*> stack_listnode;
}
ListNode* q = stack_listnode.top();
stack_listnode.pop();
while(stack_listnode.size() != 0) {
q->next = stack_listnode.top();
stack_listnode.pop();
q = q->next;
}
q->next = NULL;
}
};  ``````

The second way of thinking:

If you are a serious study of data structure students, you will think of an idea: the first method and the last method!

At this point, you must have understood. The head plug and tail plug will be described in detail in another MD;

The third way of thinking:

In short, through two pointers to climb a given list, in the process of climbing to the third pointer assignment, slowly the third pointer to form a new list. It’s a bit like DNA transcription .

``````class Solution {
public:
ListNode *p1,*p2,*p3;
p1 = NULL;
while(p2!=NULL){
p3 = p2->next;
p2->next = p1;
p1 = p2;
p2 = p3;
}
return p1;
}
};``````

# Delete intermediate node

#### Interview question 02.03. Delete intermediate node

Easy 31

Implement an algorithm to delete a node in the middle of the one-way list (that is, not the first or last node), assuming that you can only access the node.

Example:

``````Input: node C in unidirectional list a - > b - > C - > D - > e - > F
Results: no data is returned, but the linked list becomes a - > b - > D - > e - > F``````

Thinking:

The key to this question is to understand the meaning of the question.

Analysis of the theme:

The title only gives you a node, nothing else, and you can’t get the list. Let you delete this element, I think this is a good case. I can’t get the list, I can only get the node. I don’t know how many

But we can access the node after this node, and we can also access the node after this node. So this node is equal to the value of next, and then delete next, steal beam and change column.

How to delete it? In fact, just assign node > next = node > next > next directly.

``````/**
* struct ListNode {
*     int val;
*     ListNode *next;
*     ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
void deleteNode(ListNode* node) {
if(node == NULL) return ;
node->val = node->next->val;
node->next = node->next->next;
}
};``````

#### 234. Palindrome list

Easy 533

Example 1:

``````Input: 1 - > 2
Output: false``````

Example 2:

``````Input: 1 - > 2 - > 2 - > 1
Output: true``````

Can you solve this problem with O (n) time complexity and O (1) space complexity?

Idea 1:

Put it in the array and compare one by one

``````/**
* struct ListNode {
*     int val;
*     ListNode *next;
*     ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
vector<int> array;
int count = 0;
}
for(int i = 0;i < array.size() / 2; i++){
if(array[i] != array[array.size() - i - 1])
return false;
}
return true;

}
};``````

The second way of thinking:

Use the speed pointer to find the middle, turn the second half, and compare from the middle.

``````class Solution {
public:
while (fast){//find mid node
slow = slow->next;
fast = fast->next ? fast->next->next: fast->next;
}
while (slow){//reverse
ListNode* temp = slow->next;
slow->next = prev;
prev = slow;
slow = temp;
}
return false;
}
prev = prev->next;
}
return true;
}
};``````

# List summation

#### Interview question 02.05. List summation

Medium difficulty 23

Given two integers represented by linked lists, each node contains one digit.

These digits are stored in reverse, that is, they are placed at the top of the list.

Write a function to sum the two integers and return the result in the form of a linked list.

Example:

``````Input: (7 → 1 → 6) + (5 → 9 → 2), that is 617 + 295
Output: 2 → 1 → 9, that is 912``````

Advanced:If these digits are stored in the forward direction, please do it again.

Example:

``````Input: (6 → 1 → 7) + (2 → 9 → 5), that is 617 + 295
Output: 9 → 1 → 2, that is 912``````

Thinking:

The idea of this problem is very clear: the combination of linked list + carry problem. (the merging of linked lists will be specially discussed in the topic of linked lists)

``````class Solution {
public:
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
ListNode *sum = l1;
while(l1->next && l2->next)
{
l1->val += l2->val;
l1 = l1->next;
l2 = l2->next;
}
l1->val += l2->val;
if(!l1->next)
{
l1->next = l2->next;
}
l1 = sum;
while(l1->next)
{
if(l1->val >= 10)
{
l1->val -= 10;
l1 = l1->next;
l1->val++;
}
else
{
l1 = l1->next;
}
}
if(l1->val >= 10)
{
l1->val -= 10;
l1->next = new ListNode(1);
return sum;
}
else
{
return sum;
}
}
};``````

# Pat a1032 (find the first common node)

### subject

1032 sharing (25 points)

To store English words, one method is to use linked lists and store a word letter by letter. To save some space, we may let the words share the same sublist if they share the same suffix. For example, `loading` and `being` are stored as showed in Figure 1.

Figure 1

You are supposed to find the starting position of the common suffix (e.g. the position of `i` in Figure 1).

#### Input Specification:

Each input file contains one test case. For each case, the first line contains two addresses of nodes and a positive N (≤105), where the two addresses are the addresses of the first nodes of the two words, and N is the total number of nodes. The address of a node is a 5-digit positive integer, and NULL is represented by −1.

Then N lines follow, each describes a node in the format:

``Address Data Next``

where`Address` is the position of the node, `Data` is the letter contained by this node which is an English letter chosen from { a-z, A-Z }, and `Next` is the position of the next node.

#### Output Specification:

For each case, simply output the 5-digit starting position of the common suffix. If the two words have no common suffix, output `-1` instead.

#### Sample Input 1:

``````11111 22222 9
67890 i 00002
00010 a 12345
00003 g -1
12345 D 67890
00002 n 00003
22222 B 23456
11111 L 00001
23456 e 67890
00001 o 00010``````

#### Sample Output 1:

``67890``

#### Sample Input 2:

``````00001 00002 4
00001 a 10001
10001 s -1
00002 a 10002
10002 t -1``````

#### Sample Output 2:

``-1``

To find the addresses of ⾸ common nodes of two linked lists. If not, output – 1

### thinking

⽤ structure array storage, node [i] represents the node with address I, key represents the value, next represents the address of the next node, flag table

Indicates whether the node exists in the ⼀ linked list

When traversing the ⼀ linked list, the flags of the visited nodes are marked as true. When traversing the ⼆ linked list, if a true flag is encountered

Node output and end the program, did not encounter the output – 1

### Code

``````#include <cstdio>
using namespace std;
const int MAX = 100010;
struct node
{
char data;
int next;
bool flag;
}node[MAX];
int main()
{
for (int i = 0; i < MAX; i++)
{
node[i].flag = false;
}
Int S1, S2, N; // S1 and S2 are the first addresses of the two linked lists
scanf("%d%d%d",&s1, &s2, &n);
char data;
for (int i = 0; i < n; i++)
{
scanf("%d %c %d", &address, &data, &next);
}
int p;
for (p = s1; p != -1; p = node[p].next)
{
node[p].flag = true;
}
for (p = s2; p != -1; p = node[p].next)
{
if (node[p].flag == true)
{
break;
}
}
if (p != -1)
{
printf("%05d\n", p);
}
else
{
printf("-1\n");
}

return 0;
}``````

# Pat a1097 (delete nodes with the same absolute value)

### subject

1097 duplication on a linked list (25 points)

Given a singly linked list L with integer keys, you are supposed to remove the nodes with duplicated absolute values of the keys. That is, for each value K, only the first node of which the value or absolute value of its key equals K will be kept. At the mean time, all the removed nodes must be kept in a separate list. For example, given L being 21→-15→-15→-7→15, you must output 21→-15→-7, and the removed list -15→15.

#### Input Specification:

Each input file contains one test case. For each case, the first line contains the address of the first node, and a positive N (≤105) which is the total number of nodes. The address of a node is a 5-digit nonnegative integer, and NULL is represented by −1.

Then N lines follow, each describes a node in the format:

``Address Key Next``

where `Address` is the position of the node, `Key` is an integer of which absolute value is no more than 104, and `Next` is the position of the next node.

#### Output Specification:

For each case, output the resulting linked list first, then the removed list. Each node occupies a line, and is printed in the same format as in the input.

#### Sample Input:

``````00100 5
99999 -7 87654
23854 -15 00000
87654 15 -1
00000 -15 99999
00100 21 23854``````

#### Sample Output:

``````00100 21 23854
23854 -15 99999
99999 -7 -1
00000 -15 87654
87654 15 -1``````

Meaning: give a linked list, remove the duplicate (remove the value or the absolute value is equal), first output the deleted linked list, and then output the deleted linked list.

### thinking

The ⽤ structure array stores the linked list, ⼤⼩ is maxn = 100000, and node [i] represents the node with address I. Define ⼀ num variables in the structure, and initialize num variables to 2 * maxn. By changing the value of num variable, the final sort sort can change the value of linked list
Sequence.
Mark num of nodes not deleted as cnt1, and cnt1 is the number of nodes not deleted at present; mark num of nodes to be deleted as maxn + CNT2, and CNT2 represents the number of nodes deleted at present. Because ⼀ is initialized to 2 * maxn, we can
By sorting num, we can get the following results: num = 0 ~ maxn is not deleted node, Num = maxn ~ 2maxn is deleted node, Num = 2maxn is ⽆ effective node
In this way, after sort, the nodes will be sorted according to the order of output. We only need to output the first two cnt1 + CNT2 nodes

### code

``````#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
const int maxn = 100000;
struct Node {
int address, key, next, num = 2 * maxn;
}node[maxn];
bool exist[maxn];
int cmp1(Node a, Node b) {
return a.num < b.num;
}
int main() {
int begin, n, cnt1 = 0, cnt2 = 0, a;
scanf("%d%d", &begin, &n);
for (int i = 0; i < n; i++) {
scanf("%d", &a);
scanf("%d%d", node[a].key, &node[a].next);
}
for (int i = begin; i != -1; i = node[i].next) {
if (exist[abs(node[i].key)] == false) {
exist[abs(node[i].key)] = true;
node[i].num = cnt1;
cnt1++;
}
else {
node[i].num = maxn + cnt2;
cnt2++;
}
}
sort(node, node + maxn, cmp1);
int cnt = cnt1 + cnt2;
for (int i = 0; i < cnt; i++) {
if (i != cnt1 - 1 && i != cnt - 1) {
}
else {