CareerCup chapter 2 Linked Lists
2014-06-02 10:24
381 查看
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;
}
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;
}
相关文章推荐
- CareerCup chapter 3 Stacks and Queues
- CareerCup Chapter 9 Sorting and Searching
- CareerCup chapter 8 Recursion
- CareerCup chapter 5 Bit Manipulation
- CareerCup Chapter 4 Trees and Graphs
- CareerCup chapter 1 Arrays and Strings
- careercup-中等难度 17.3
- Chapter 2 Linked Lists - 2.5
- Recursion 计算表达式的括号组合 @CareerCup
- Moderate 最大连续序列之和 @CareerCup
- Hard 计算0到n之间2的个数 @CareerCup
- Arrays_Strings 判断字符串中的字符是否唯一@CareerCup
- CareerCup Cost of cutting wood
- Stack_Queue 两个栈实现一个队列 @CareerCup
- Tree_Graph Inorder Successor in Binary Search Tree BST中找中序遍历的后继节点 @CareerCup
- CareerCup Fermat point of a traingle
- CareerCup Given a dictionary, how would you add spaces in this string
- 奋笔疾书C++之CareerCup——面试前期准备
- careercup1.3: remove duplicate without extra space.
- Moderate 查单词 @CareerCup