Here, the struct of all linked list is:
struct ListNode{
int val;
ListNode* next;
ListNode(int val):val(val),next(NULL){}
};
1.Write code to remove duplicates from an unsorted linked list
FOLLOW UP
How would you solve this problem if a temporary buffer is not allowed?
Cannot use temporary buffer and the linked list is unsorted. We can loop the list from front, at the current node, we loop the node from its next to the tail to delete all nodes that equal to it.
ListNode* removeDuplicates(ListNode* head){
if(head==NULL)return;
ListNode *cur=head,*loopcur=NULL;
while(cur){
loopcur=cur;
while(loopcur->next){
if(loopcur->next->val == cur->val){
loopcur->next=loopcur->next->next;
}else loopcur=loopcur->next;
}
cur=cur->next;
}
return head;
}
2.Implement an algorithm to find the nth to last element of a singly linked list.
Declare two variables represent cur position and a position nth to the current. When the second pointer points to NULL of the end of this linked list, the cur pointer is the result. Here, we define that, when the length of linked list is smaller than n, we return the head.
ListNode* findNthToLast(ListNode* head,int n){
if(head==NULL||n<=0)return head;
ListNode * cur=head,*last=head;
while(n--&&last){last=last->next;}
if(n>0)return head;
while(last){
cur = cur->next;
last = last->next;
}
return cur;
}
3.Implement an algorithm to delete a node in the middle of a single linked list, given only access to that node
EXAMPLE
Input: the node ‘c’ from the linked list a->b->c->d->e
Result: nothing is returned, but the new linked list looks like a->b->d->e
Declare two pointers: cur and last. cur points a pointer whose speed is one each time, and last points a pointer whose speed is two each time. last pointer move first, we it point NULL of the end of this linked list, then cur pointer is the result.
Here, when the sum nodes of the linked list is even ,we delete the front of two middle nodes.
ListNode* deleteMiddleNode(ListNode* head){
if(head==NULL)return NULL;
ListNode *cur=head,*curpre=head,*last=head->next;
while(last){
last=last->next;
if(last)last=last->next;
else break;
curpre=cur;
cur=cur->next;
}
if(curpre==head)return head->next;
else{
curpre->next=curpre->next->next;
return head;
}
}
4.You have two numbers represented by a linked list, where each node contains a sin- gle digit The digits are stored in reverse order, such that the 1’s digit is at the head of the list Write a function that adds the two numbers and returns the sum as a linked list
EXAMPLE
Input: (3 -> 1 -> 5) + (5 -> 9 -> 2)
Output: 8 -> 0 -> 8
we store the sum to a, and declare a variable temp to store whether carry at current addition, and a variable to store the addition result at current position.
ListNode *sum(ListNode* a,ListNode *b){
if(a==NULL)return b;
if(b==NULL)return a;
ListNode *res=a,*tail;
int temp=0,addres = 0;
while(a&&b){
a->val = a->val+b->val+temp;
temp=a->val/10;a->val=a->val%10;
tail=a;
a=a->next;b=b->next;
}
while(a){
if(temp){
a->val += temp;
temp=a->val/10;a->val%=10;
tail = a;a=a->next;
}else return head;
}
if(b)tail->next=b;
while(b){
if(temp){
b->val += temp;
temp=b->val/10;b->val%=10;
tail = b;b=b->next;
}else return head;
}
if(temp){
ListNode *node = new ListNode(temp);
tail->next = node;
}
return head;
}
5.Given a circular linked list, implement an algorithm which returns node at the beginning of the loop
DEFINITION
Circular linked list: A (corrupt) linked list in which a node’s next pointer points to an earlier node, so as to make a loop in the linked list
EXAMPLE
input: A -> B -> C -> D -> E -> C [the same C as earlier]
output: C
catching up problem in linked list. We declare two pointers: a and b. A 's speed is 1 each time and B's speed is 2 each time. They will meet in the circular. Then we put a to point the head, and move a and b at the same time, whose step is 1 each time. When they meet, the position is the beginning of the loop.
Following is a briefly demonstrate:
at first, a's speed is 1 and b's speed is 2, when they meet, the length of a is m+x, and the length of b is m+c(x+y), and m+c(x+y)=2(m+x);
so, (c-2)(x+y)+2x=2m, so m=x, which means we can arrive at the beginning of the loop.
Here, m is the length before the loop, and x is the length of a moving int the loop, y is the remain length of the loop.
ListNode* findBeginningLoop(ListNode *head){
if(head==NULL)return NULL;
ListNode *a=head,*b=head;
while(b){
a=a->next;
b=b->next;if(b)b=b->next;
if(a==b)break;
}
if(b==NULL)return NULL;
a=head;
while(a!=b){
a=a->next;
b=b->next;
}
return a;
}