You are on page 1of 11

Reversal of Linked list

Recursive:

class Solution {
public:
ListNode* reverse(ListNode* head, ListNode *before){
if(head -> next == NULL){
head -> next = before;
return head;
}

ListNode * start = reverse(head -> next, head);


head -> next = before;
return start;
}

ListNode* reverseList(ListNode* head) {

if(!head) return head;


ListNode* ans = reverse(head, NULL);
return ans;

}
};

Iterative:

class Solution {
public:

ListNode* reverseList(ListNode* head) {

if(!head) return head;

ListNode *before = NULL;

while(head != NULL){
ListNode *after = head -> next;
head -> next = before;
before = head;
head = after;
}
return before;
}
};
Detect Cycle in a linked list

class Solution {
public:
bool hasCycle(ListNode *head) {
// // O(N) space

// map<ListNode*, bool> m;
// ListNode *curr = head;
// while(curr){
// if(m[curr]) return true;
// m[curr] = 1;
// curr = curr -> next;
// }
// return false;

// O(1) space

ListNode *slow = head, *fast = head;


while(fast && fast -> next){
slow = slow->next;
fast = fast -> next -> next;

if(slow == fast) return true;


}
return false;
}
};

Find node cycle point

ListNode *detectCycle(ListNode *head) {


// find meeting point;
ListNode *slow = head, * fast = head;

while(fast and fast -> next){


slow = slow -> next;
fast = fast -> next -> next;
if(slow == fast) break;
}
if(!fast or !fast -> next) return NULL;
ListNode *start = head;
while(start != slow){
start = start -> next;
slow = slow -> next;
}
return start;
}

Merget Two sorted lists

class Solution {
public:

ListNode* mergeTwoLists(ListNode* list1, ListNode* list2) {

// if either is null
if(!list1) return list2;
if(!list2) return list1;

if(list1 -> val <= list2 -> val){


ListNode* l1 = mergeTwoLists(list1 -> next, list2);
list1 -> next = l1;
return list1;
}else{
ListNode *l2 = mergeTwoLists(list1, list2 -> next);
list2 -> next = l2;
return list2;
}
}
};

Merge K sorted Lists

class cmp{
public:
bool operator () (ListNode *a, ListNode *b){
return a->val > b->val ;
}
};
class Solution {
public:
ListNode* mergeKLists(vector<ListNode*>& lists) {
int n = lists.size();
// get smallest element of all top of list
priority_queue<ListNode*, vector<ListNode*>, cmp> pq;
for(int i = 0; i < n; i++){
if(lists[i]) pq.push(lists[i]);
}
ListNode *dummy = new ListNode(-1);
ListNode *tail = dummy;
while(!pq.empty()){
ListNode* currLow = pq.top(); pq.pop();
tail -> next = currLow;
tail = currLow;
if(currLow-> next) pq.push(currLow -> next);

}
return dummy -> next;

}
};

Remove duplicates from a sorted list

ListNode* deleteDuplicates(ListNode* head) {


if(!head or !head-> next) return head;
ListNode *prev = head, *curr = head -> next;
while(curr){
if(prev -> val == curr -> val){
prev -> next = curr -> next;
}else prev = curr;
curr = curr -> next;
}
return head;
}

Remove duplicate number from a sorted list II

class Solution {
public:

ListNode* findLastDup(ListNode *node){


while( node -> next){
if(node -> val == node -> next -> val){
node = node -> next;
}else break;
}
return node;
}

ListNode* deleteDuplicates(ListNode* head) {


if(!head) return NULL;
ListNode *prev = NULL, *curr = head, *after = head -> next;

while(curr){
if(after and curr -> val == after -> val){
ListNode *last = findLastDup(curr);
if(prev) prev-> next = last -> next;
else{
head = last -> next;
}
curr = last -> next;
if(curr) after = curr -> next;

}else {
prev = curr;
curr = curr -> next;
if(curr)
after = curr -> next;
}
}
return head;
}
};

Remove duplicates from unsorted list

class Solution
{
public:
//Function to remove duplicates from unsorted linked list.
Node * removeDuplicates( Node *head)
{
// your code goes here
Node *prev = new Node(0), *curr = head;
prev -> next = head;
map<int, bool> m;

while(curr){
if(m[curr -> data]){
// delete node
prev -> next = curr -> next;
curr = curr -> next; continue;
}
m[curr -> data] = true;
prev = curr;
curr = curr -> next;
}
return head;
}
};

Intersection of two linked lists

class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
ListNode *currA = headA, *currB = headB;

while(currA != currB){
if(!currA) currA = headB;
else currA = currA->next;

if(!currB) currB = headA;


else currB = currB->next;
}

return currA;
}
};
Check if a linked list is palindrom of not with constant space

class Solution {
public:
// tc: O(N), sc: O(1);
ListNode* reverse(ListNode *head){
if(!head) return NULL;

ListNode *prev = NULL, *curr = head;


while(curr){
ListNode *after = curr->next;
curr-> next = prev;
prev = curr;
curr = after;
}
// return the head of the reversed node;
return prev;
}

bool isPalindrome(ListNode* head) {


// find first middle element;
if(!head or !head->next) return head;
ListNode *slow = head, *fast = head;

while(fast->next and fast->next->next){

slow = slow->next;
fast = fast->next->next;
}

// reverse from the next of middle element


slow -> next = reverse(slow->next);

ListNode *ptr1 = head, *mid = slow -> next;


while(mid){
if(mid -> val != ptr1 -> val) return false;
mid = mid -> next;
ptr1 = ptr1 -> next;
}

// reverse the linked list to its original form as we dont need altered structure
slow -> next = reverse(slow->next);
return true;
}
};

Reorder Lists

class Solution {
public:

ListNode* reverse(ListNode *head){


if(!head) return NULL;

ListNode *prev = NULL, *curr = head;

while(curr){
ListNode* after = curr -> next;
curr -> next = prev;
prev = curr;
curr = after;
}
return prev;
}
void reorderList(ListNode* head) {
// find first middle element

ListNode* fast = head, *slow = head;

while(fast -> next and fast -> next -> next){


fast = fast -> next-> next;
slow = slow -> next;
}

// reverse the second half

ListNode *ptr2 = reverse(slow-> next);


slow->next = NULL;

ListNode *ptr1 = head;

// merge two lists


while(ptr1 and ptr2){
ListNode *p1after = ptr1->next;
ListNode *p2after = ptr2->next;
ptr1->next = ptr2;
ptr1 = p1after;
ptr2 -> next = ptr1;
ptr2 = p2after;
}
}
};

Reversal of a doubly linked list

Node* reverseDLL(Node * head)


{
//Your code here
Node *curr = head, *prev = NULL, *after = head->next;

while(curr){
curr->prev = after;
curr-> next = prev;
prev = curr;
curr = after;
if(after) after = after -> next;
}
return prev;
}

Intersection of two lists


Node* findIntersection(Node* head1, Node* head2)
{
// Your Code Here
Node* ptr1 = head1, *ptr2 = head2;
Node* dummy = new Node(-1);
Node* tail = dummy;
while(ptr1 and ptr2){
if(ptr1->data == ptr2->data){
Node* node = new Node(ptr1->data);
tail->next = node;
tail = node;
ptr1 = ptr1->next;
ptr2 = ptr2->next;
}else if(ptr1-> data > ptr2->data){
ptr2 = ptr2->next;
}else{
ptr1 = ptr1->next;
}
}
return dummy->next;
}

Reverse nodes in K-group

K =3

Recursion Recursion Recursion

Return 3 Return 4 Return 7, don’t reverse


class Solution {
public:

pair<ListNode*, ListNode*> reverse(ListNode* head, int k, int len){

if(len < k) return {head, NULL};

ListNode* prev = NULL, * curr = head;

// only reverse k nodes


while(k--){
ListNode* after = curr->next;
curr->next = prev;
prev = curr;
curr = after;
}
return {prev, curr};
}

ListNode* rkg(ListNode* head, int k, int len){

// run out of nodes (base cond)


if(!head) return NULL;

pair<ListNode*, ListNode*> nodes = reverse(head, k, len);


ListNode* newHead = nodes.first, *nextBatch = nodes.second;

// newHead.next is the newHead of next group


ListNode* otherBatchHead = rkg(nextBatch, k, len - k);

// only if other batch does has head


if(otherBatchHead) head -> next = otherBatchHead;

return newHead;
}

ListNode* reverseKGroup(ListNode* head, int k) {

// get length of list, so we dont reverse groups < k


int len = 0;
ListNode* curr = head;
while(curr){
len++; curr = curr-> next;
}

return rkg(head, k, len);


}
};

You might also like