Partitioning a linked list - algorithm

I am trying to solve this algorithmic problem based on linked list data structure. The question is as follows:
Given a linked list and a value x, partition it such that all nodes less than x come before nodes greater than or equal to x.
You should preserve the original relative order of the nodes in each of the two partitions.
For example,
Given 1->4->3->2->5->2 and x = 3,
return 1->2->2->4->3->5.
My solution to the problem is:
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
public class Solution {
public ListNode partition(ListNode head, int x) {
if(head == null) return null;
ListNode headNode = new ListNode(-1);
headNode.next = head;
ListNode tail = head;
while(tail.next!=null){
tail = tail.next;
}
ListNode actualTail = tail;
ListNode current = headNode;
while(current!=actualTail && current.next!=actualTail){
if(current.next.val >= x && current.next!=tail){
System.out.println("Moving "+current.next.val+" to end of list, ahead of "+tail.val);
ListNode temp = current.next;
current.next = current.next.next;
tail.next = temp;
tail = tail.next;
tail.next = null;
}else{
current = current.next;
}
}
return headNode.next;
}
}
While some test cases work fine with this code such as the one mentioned above, there are a set of test cases that fail, in that I am unable to maintain the original relative ordering of the nodes in the list.
For example:
list = [1->2]
x = 0
My result:
[2,1]
Expected:
[1,2]
Any help would be greatly appreciated.

I think you can do it in a simpler way:
Keep 2 lists, one for lower nodes and other for greater nodes.
Iterate the list adding the nodes to the corresponding list.
Concatenate the lower list with greater list
Something like this:
public ListNode Partition(ListNode head, int x)
{
ListNode lowerHead = null, lowerTail = null; //Head and Tail of lower list
ListNode greaterHead = null, greaterTail = null; //Head and Tail of greater list
ListNode current = head;
while (current != null)
{
if (current.val < x)
{
if (lowerHead == null) lowerHead = current; //If is the first node in the list
if (lowerTail == null) lowerTail = current; //set the head an tail to the same value
else lowerTail = lowerTail.next = current; //Otherwise, add the node and update the tail
}
else
{
if (greaterHead == null) greaterHead = current; //If is the first node in the list
if (greaterTail == null) greaterTail = current; //set the head an tail to the same value
else greaterTail = greaterTail.next = current; //Otherwise, add the node and update the tail
}
current = current.next;
}
if (greaterHead != null)
greaterTail.next = null;
if (lowerHead == null) return greaterHead;
else
{
lowerTail.next = greaterHead;
return lowerHead;
}
}
Order is preserved since nodes are added as they appear in the original list

It can be done in place, in O(N) time O(1) space. Just keep
track of the immediate preceding node, before the first node, that is
greater than or equal to the X.
This node acts as the boundary between the nodes that are less than X
and nodes that are greater than or equal to X.
Refer the code along with inline comments.
class Solution {
public ListNode partition(ListNode head, int x) {
// Assume that list has at least one instance of X and x = 3
ListNode dummy = new ListNode(-1);
dummy.next = head;
ListNode prev = dummy;
ListNode curr = head;
// Keeps track of the preceding node, before the first value greater than or equal to x.
ListNode large = null;
// Tracks weather the first node greater than or equal to x has been found.
boolean isFirstLargeFound = false;
while(curr != null) {
if (curr.val >= x) {
if (!isFirstLargeFound) {
large = prev;
isFirstLargeFound = true;
}
} else if (isFirstLargeFound) {
// If the current value is less than x and the first larger value has
// been found, we need to swap the nodes.
//
// Consider the example: 1->4->0->3->2->5, the curr node is at value 0.
// At this point of time the first larger value i.e. 4 has been already
// found, hence we have to move the Node with value 0 to a place before
// the node with value 4.
//
// Before: 1->4->0->3->2->5
// After: 1->0->4->3->2->5
ListNode temp = large.next;
prev.next = curr.next;
large.next = curr;
// Ensures that the first element that is >=X, is always next of large node.
curr.next = temp;
large = large.next;
}
prev = curr;
curr = curr.next;
}
return dummy.next;
}
}

I solved it in Python and works fine.
current = runner = ll.head
while runner:
if runner.value < part:
temp = current.value
current.value = runner.value
runner.value = temp
current = current.next
runner = runner.next
else:
runner = runner.next

Even though this is an bit old thread, I hope this will be useful for someone.
class ListNode:
def __init__(self, x):
self.val = x
self.next = None
class LinkedList:
def __init__(self):
self.head = None
self.tail = None
def insert_node(self, val):
new_node = ListNode(val)
if self.head is None:
self.head = self.tail = new_node
else:
self.tail.next = new_node
self.tail = new_node
class Solution:
def partition(self, head: ListNode, x: int) -> ListNode:
if head is None or head.next is None:
return head
else:
tmp = head
low = LinkedList()
high = LinkedList()
while tmp is not None:
if tmp.val < x:
low.insert_node(tmp.val)
else:
high.insert_node(tmp.val)
tmp = tmp.next
if low.head is not None:
tail = low.head
while tail.next is not None:
tail = tail.next
tail.next = high.head
output = low.head
else:
output = high.head
return output

Related

Crush Linked list nodes

Given a linked list how do i crush all more than two nodes which are continuous and have same value.
eg
1->3->3->3->5->4->4->4->5->5->2->5
step1 crush 3
1->5->4->4->4->5->5->2->5
step2 crush 4
1->5->5->5->2->5
step3 crush 5
return 1->2->5
I tried below code but its returning 1->5->->5->2->5
public void Crush()
{
Node prev = null, current = head;
if (head == null)
{
return;
}
prev = current;
while (current.next != null)
{
int k = 0;
while (current != null && current.next != null && current.data == current.next.data)
{
k++;
current = current.next;
}
if (k < 2)
{
// prev.next = current;
current = current.next;
}
else
{
prev.next = current.next;
current = current.next;
}
}
head = prev;
}
1->3->3->3->5->4->4->4->5->5->2->5
^
1->5->5->5->2->5
^
When you remove the run of 4s, it creates a new run of 5s. However, the first 5 has already been skipped over, so only 2 5s are counted.
Anytime a run is removed, you'll need to reprocess the list from the beginning.

How to build an incomplete binary tree from array representation

if the input is an array, where null means no node.
input:
[1, 2, 3, null, 5, null, 7]
Please assume that I have already checked the input.
For each array[i], its parents array[i / 2] will not be null (recursively, so root can not be null).
How to build a tree with such logic relation:
1
/ \
2 3
\ \
5 7
each node should be represented by a TreeNode object:
class TreeNode {
public:
int val;
TreeNode *left;
TreeNode *right;
TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
};
I found a blog here where a complete tree was built
but if the tree is incomplete as mentioned above, how to do it neatly and efficiently ?
Test data:
[input array]
[-64,12,18,-4,-53,null,76,null,-51,null,null,-93,3,null,-31,47,null,3,53,-81,33,4,null,-51,-44,-60,11,null,null,null,null,78,null,-35,-64,26,-81,-31,27,60,74,null,null,8,-38,47,12,-24,null,-59,-49,-11,-51,67,null,null,null,null,null,null,null,-67,null,-37,-19,10,-55,72,null,null,null,-70,17,-4,null,null,null,null,null,null,null,3,80,44,-88,-91,null,48,-90,-30,null,null,90,-34,37,null,null,73,-38,-31,-85,-31,-96,null,null,-18,67,34,72,null,-17,-77,null,56,-65,-88,-53,null,null,null,-33,86,null,81,-42,null,null,98,-40,70,-26,24,null,null,null,null,92,72,-27,null,null,null,null,null,null,-67,null,null,null,null,null,null,null,-54,-66,-36,null,-72,null,null,43,null,null,null,-92,-1,-98,null,null,null,null,null,null,null,39,-84,null,null,null,null,null,null,null,null,null,null,null,null,null,-93,null,null,null,98]
I think this example can explain what's in your mind .
array : [5,4,8,11,null,17,4,7,null,null,null,5]
Tree :
5
/ \
4 8
/ / \
11 17 4
/ /
7 5
All answer above are regard input array as a full tree. So left.child=2idx+1 , right.child = 2idx+2 but is actually it's wrong .
beacuse those
[5,4,8,11,null,17,4,7,null,null,null,5]
[5,4,8,11,null,17,4,7,null,null,null,null,null,5,null]
are different
here is my solution
public static TreeNode createTree(Integer[] array) {
if (array == null || array.length==0) {
return null;
}
Queue<TreeNode> treeNodeQueue = new LinkedList<>();
Queue<Integer> integerQueue = new LinkedList<>();
for (int i = 1; i < array.length; i++) {
integerQueue.offer(array[i]);
}
TreeNode treeNode = new TreeNode(array[0]);
treeNodeQueue.offer(treeNode);
while (!integerQueue.isEmpty()){
Integer leftVal = integerQueue.isEmpty() ? null : integerQueue.poll();
Integer rightVal = integerQueue.isEmpty() ? null : integerQueue.poll();
TreeNode current = treeNodeQueue.poll();
if (leftVal !=null) {
TreeNode left = new TreeNode(leftVal);
current.left = left;
treeNodeQueue.offer(left);
}
if (rightVal !=null){
TreeNode right = new TreeNode(rightVal);
current.right = right;
treeNodeQueue.offer(right);
}
}
return treeNode;
}
When implementing a binary tree as an array it helps to have a
clear visualization of how the two representations mirror one
another, and review the mathematical structure that underlines
the relationship.
If we consider 0-indexed arrays the mathematical relation can
be broken down as such,
The root node has index 0
For the i:th node (i is the array index) we have that (verify)
The left-child of the node has the index 2i + 1
The right-child of the node has the index 2(i + 1)
The parent of a node has the index floor((i-1)/2)
So, for the binary tree
if we let - denote null, is represented as such
[0:a, 1:b, 2:c, 3:d, 4:e, 5:-, 6:-, 7:-, 8:-, 9:g, 10:-, 11:-, 12:-, 13:-, 14:-]
So now to create the OO representation from the array you simply apply these indexing rules. So, since you know that the root node is a then we get its children at:
Left: 2*0 + 1 = 1 => b
Right: 2*(0 + 1) = 2 => c
Pseudo code
for (int idx = 0; 2*(idx + 1) < len(arr); idx++) {
if (arr[idx] == null) {
// There is no node to add for this index
continue;
}
TreeNode t = null;
if (idx == 0) {
// Root node case
t = TreeNode(val: arr[idx]);
binary_tree.add(id: idx, node: t);
}
// We do not know if these exist yet
int left_idx = 2*idx + 1;
int right_idx = 2*(idx + 1);
if (left_idx >= len(arr)) {
// left_idx is out of bounds with respect to the array,
// and by extension so would the right node be
continue;
}
TreeNode left = null;
TreeNode right = null;
if (arr[left_idx] != null) {
// This node has never been encountered before
// and it is non-null so it must be created.
//
// Since we know we have a root node then there is
// no need to check if the tree already contains this
// node, it simply is not possible. Ditto for the right
// node.
left = TreeNode(val: arr[left_idx]);
binary_tree.add(id: left_idx, node: left);
}
if (right_idx >= len(arr)) {
// There cannot be a right child
continue;
}
if (arr[right_idx] != null) {
// This node has never been encountered before
// and it is non-null so it must be created.
right = TreeNode(val: arr[right_idx]);
binary_tree.add(id: right_idx, right);
}
// It does not matter if left or right is null
t.set_left(left)
t.set_right(right)
}
Thanks Steven. I converted the Java code from Steven into Python. It worked for me!
class TreeNode:
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right
def creatBTree(data):
if data == None or len(data) == 0:
return None
treeNodeQueue = []
integerQueue = []
for i in range(1,len(data)):
print(i)
integerQueue.append(data[i])
treeNode = TreeNode(data[0])
treeNodeQueue.append(treeNode)
while integerQueue:
if integerQueue:
leftVal = integerQueue.pop(0)
if integerQueue:
rightVal = integerQueue.pop(0)
current = treeNodeQueue.pop(0)
if leftVal is not None:
left = TreeNode(leftVal)
current.left = left
treeNodeQueue.append(left)
if rightVal is not None:
right = TreeNode(rightVal)
current.right = right
treeNodeQueue.append(right)
return treeNode
Just use recursion to traverse the nodes using the index of the array and use Integer to allow null.
private TreeNode array2Tree(Integer[] data,TreeNode root, int index){
if(index >= data.length){
return root;
}
if(data[index] != null){
TreeNode temp = new TreeNode(data[index]);
root = temp;
root.left = array2Tree(data,root.left,2*index+1);
root.right = array2Tree(data,root.right,2*index+2);
}
return root;
}
I have replaced null with -1 for simplicity
arr = [1, 2, 3, -1, -1, 5,6,-1,-1,-1,-1, 7, 8, -1, -1]
Now this given method insert will create a complete binary from above array then convertMinus1IntoNone function will remove all nodes with -1 and make proper tree as needed in question.
from collections import deque
class Node:
def __init__(self, val):
self.val = val
self.left = None
self.right = None
def insert(root, val):
newnode = Node(val)
if not root:
root = newnode
return root
Q = deque([root])
while Q:
node = Q.popleft()
if not node.left:
node.left = newnode
return
if not node.right:
node.right = newnode
return
else:
Q.append(node.left)
Q.append(node.right)
def convertMinus1IntoNone(root):
if root is None:
return
if root.left!= None:
convertMinus1IntoNone(root.left)
if root.left.val == -1:
root.left = None
if root.right!= None:
convertMinus1IntoNone(root.right)
if root.right.val == -1:
root.right = None
arr = [1, 2, 3, -1, -1, 5,6,-1,-1,-1,-1, 7, 8, -1, -1]
root = insert(None, arr[0])
for i in range(1, len(arr) , 1):
insert(root, arr[i])
convertMinus1IntoNone(root)
In Java:
public class TreeNode {
public int val;
public TreeNode left;
public TreeNode right;
public TreeNode() {}
public TreeNode(int val) { this.val = val; }
public TreeNode(int val, TreeNode left, TreeNode right) {
this.val = val;
this.left = left;
this.right = right;
}
/**
* Create a tree from array using levels i.e {-2,3,4,null,null,5,null,null,null,null,null, 6 } becomes 2 le-> 3, 2 re->4, 4 le->5, 5 le->6
* #param arr the arr to be converted to a tree
* #return
*/
public static TreeNode createTreeFromArray(Integer[] arr){
TreeNode root = new TreeNode();
return insertLevelOrder(arr, root, 0);
}
static TreeNode insertLevelOrder(Integer[] arr, TreeNode root,
int i)
{
// Base case for recursion
if (i < arr.length) {
if(arr[i] == null)
return null;
TreeNode temp = new TreeNode(arr[i]);
root = temp;
// insert left child
root.left = insertLevelOrder(arr, root.left,
2* i + 1);
// insert right child
root.right = insertLevelOrder(arr, root.right,
2* i + 2);
}
return root;
}
}

Pseudocode for Binary search tree

In a binary search tree, the predecessor of a key x is a key y that is smaller than
x, and for which there is no other key z such that z is smaller than x and greater
than y.
Give the pseudocode for an algorithm that takes a key x and returns the
predecessor y or nil if x is the smallest key in the tree. Assume that the binary
search tree is represented using arrays left, right, and parent. Give the pseudocode
for any subsidiary functions that are used.
I'm not really sure how to approach this question. But heres my attempt:
Pseudocode:
//Takes in key x
BST(x)
{
if ( x < parent[x] )
return nil
if( parent[x] < x )
return parent[x] // parent[x] = y
}
My previous answer was from a poor readover of your question - what you are looking for is just the predecessor in the tree.
http://www.quora.com/How-can-you-find-successors-and-predecessors-in-a-binary-search-tree-in-order
here is the code they use in that post:
public static TreeNode findPredecessor(TreeNode node)
{
if (node == null)
return null;
if (node.getLeft() != null)
return findMaximum(node.getLeft());
TreeNode parent = node.getParent();
TreeNode y = parent;
TreeNode x = node;
while (y != null && x == y.getLeft())
{
x = y;
y = y.getParent();
}
return y;
}
If there is no any left node present then there cant be any predecessor. Otherwise max element in left subtree will be the predecessor
public int findmax(Node root) {
if (root == NULL)
return INT_MIN;
int res = root->data;
int lres = findMax(root->left);
int rres = findMax(root->right);
if (lres > res)
res = lres;
if (rres > res)
res = rres;
return res;
}
public int findPredecessor(Node node) {
if(node == null) return null;
if(node->left == null) return null;
return findMax(node->left);
}

Dynamic prefix sum

Is there any data structure which is able to return the prefix sum [1] of array, update an element, and insert/remove elements to the array, all in O(log n)?
[1] "prefix sum" is the sum of all elements from the first one up to given index
For example, given the array of non-negative integers 8 1 10 7 the prefix sum for first three elements is 19 (8 + 1 + 10). Updating the first element to 7, inserting 3 as the second element and removing the third one gives 7 3 10 7. Again, the prefix sum of first three elements would be 20.
For prefix sum and update, there is Fenwick tree. But I don't know how to handle the addition/removal in O(log n) with it.
On the other hand, there are several binary search trees such as Red-black tree, all of which handle the update/insert/remove in logarithmic time. But I don't know how to maintain the given ordering and do the prefix sum in O(log n).
A treap with implicit keys can perform all this operations in O(log n) time per query. The idea of implicit keys is pretty simple: we do not store any keys in nodes. Instead, we maintain subtrees' sizes for all nodes and find an appropriate position when we add or remove an element using this information.
Here is my implementation:
#include <iostream>
#include <memory>
struct Node {
int priority;
int val;
long long sum;
int size;
std::shared_ptr<Node> left;
std::shared_ptr<Node> right;
Node(long val):
priority(rand()), val(val), sum(val), size(1), left(), right() {}
};
// Returns the size of a node owned by t if it is not empty and 0 otherwise.
int getSize(std::shared_ptr<Node> t) {
if (!t)
return 0;
return t->size;
}
// Returns the sum of a node owned by t if it is not empty and 0 otherwise.
long long getSum(std::shared_ptr<Node> t) {
if (!t)
return 0;
return t->sum;
}
// Updates a node owned by t if it is not empty.
void update(std::shared_ptr<Node> t) {
if (t) {
t->size = 1 + getSize(t->left) + getSize(t->right);
t->sum = t->val + getSum(t->left) + getSum(t->right);
}
}
// Merges the nodes owned by L and R and returns the result.
std::shared_ptr<Node> merge(std::shared_ptr<Node> L,
std::shared_ptr<Node> R) {
if (!L || !R)
return L ? L : R;
if (L->priority > R->priority) {
L->right = merge(L->right, R);
update(L);
return L;
} else {
R->left = merge(L, R->left);
update(R);
return R;
}
}
// Splits a subtree rooted in t by pos.
std::pair<std::shared_ptr<Node>, std::shared_ptr<Node>> split(
std::shared_ptr<Node> t,
int pos, int add) {
if (!t)
return make_pair(std::shared_ptr<Node>(), std::shared_ptr<Node>());
int cur = getSize(t->left) + add;
std::pair<std::shared_ptr<Node>, std::shared_ptr<Node>> res;
if (pos <= cur) {
auto ret = split(t->left, pos, add);
t->left = ret.second;
res = make_pair(ret.first, t);
} else {
auto ret = split(t->right, pos, cur + 1);
t->right = ret.first;
res = make_pair(t, ret.second);
}
update(t);
return res;
}
// Returns a prefix sum of [0 ... pos]
long long getPrefixSum(std::shared_ptr<Node>& root, int pos) {
auto parts = split(root, pos + 1, 0);
long long res = getSum(parts.first);
root = merge(parts.first, parts.second);
return res;
}
// Adds a new element at a position pos with a value newValue.
// Indices are zero-based.
void addElement(std::shared_ptr<Node>& root, int pos, int newValue) {
auto parts = split(root, pos, 0);
std::shared_ptr<Node> newNode = std::make_shared<Node>(newValue);
auto temp = merge(parts.first, newNode);
root = merge(temp, parts.second);
}
// Removes an element at the given position pos.
// Indices are zero-based.
void removeElement(std::shared_ptr<Node>& root, int pos) {
auto parts1 = split(root, pos, 0);
auto parts2 = split(parts1.second, 1, 0);
root = merge(parts1.first, parts2.second);
}
int main() {
std::shared_ptr<Node> root;
int n;
std::cin >> n;
for (int i = 0; i < n; i++) {
std::string s;
std::cin >> s;
if (s == "add") {
int pos, val;
std::cin >> pos >> val;
addElement(root, pos, val);
} else if (s == "remove") {
int pos;
std::cin >> pos;
removeElement(root, pos);
} else {
int pos;
std::cin >> pos;
std::cout << getPrefixSum(root, pos) << std::endl;
}
}
return 0;
}
An idea: to modify an AVL tree. Additions and deletions are done by index. Every node keeps the count and the sum of each subtree to allow all operations in O(log n).
Proof-of-concept with add_node and update_node and prefix_sum implemented:
class Node:
def __init__(self, value):
self.value = value
self.left = None
self.right = None
self.left_height = 0
self.right_height = 0
self.left_count = 1
self.left_sum = value
self.right_count = 0
self.right_sum = 0
def set_value(self, value):
self.value = value
self.left_sum = self.left.left_sum + self.left.right_sum+self.value if self.left else self.value
def set_left(self, node):
self.left = node
self.left_height = max(node.left_height, node.right_height)+1 if node else 0
self.left_count = node.left_count + node.right_count+1 if node else 1
self.left_sum = node.left_sum + node.right_sum+self.value if node else self.value
def set_right(self, node):
self.right = node
self.right_height = max(node.left_height, node.right_height)+1 if node else 0
self.right_count = node.left_count + node.right_count if node else 0
self.right_sum = node.left_sum + node.right_sum if node else 0
def rotate_left(self):
b = self.right
self.set_right(b.left)
b.set_left(self)
return b
def rotate_right(self):
a = self.left
self.set_left(a.right)
a.set_right(self)
return a
def factor(self):
return self.right_height - self.left_height
def add_node(root, index, node):
if root is None: return node
if index < root.left_count:
root.set_left(add_node(root.left, index, node))
if root.factor() < -1:
if root.left.factor() > 0:
root.set_left(root.left.rotate_left())
return root.rotate_right()
else:
root.set_right(add_node(root.right, index-root.left_count, node))
if root.factor() > 1:
if root.right.factor() < 0:
root.set_right(root.right.rotate_right())
return root.rotate_left()
return root
def update_node(root, index, value):
if root is None: return root
if index+1 < root.left_count:
root.set_left(update_node(root.left, index, value))
elif index+1 > root.left_count:
root.set_right(update_node(root.right, index - root.left_count, value))
else:
root.set_value(value)
return root
def prefix_sum(root, index):
if root is None: return 0
if index+1 < root.left_count:
return prefix_sum(root.left, index)
else:
return root.left_sum + prefix_sum(root.right, index-root.left_count)
import random
tree = None
tree = add_node(tree, 0, Node(10))
tree = add_node(tree, 1, Node(40))
tree = add_node(tree, 1, Node(20))
tree = add_node(tree, 2, Node(70))
tree = update_node(tree, 2, 30)
print prefix_sum(tree, 0)
print prefix_sum(tree, 1)
print prefix_sum(tree, 2)
print prefix_sum(tree, 3)
print prefix_sum(tree, 4)

Given a linked list of numbers. Swap every 2 adjacent links

Given a linked list of numbers. Swap every 2 adjacent links. For example, if a linked list given to you is:
a->b->c->d->e->f
Output expected:
b->a->d->c->f->e
Every 2 alternate links have to be swapped.
I have written a solution here. Can you suggest me some other solution. Can you comment on my solution and help me better write it?
void SwapAdjacentNodes (Node head)
{
if (head == null) return;
if (head.next == null) return;
Node curr = head;
Node next = curr.Next;
Node temp = next.Next;
while (true)
{
temp = next.Next;
next.Next = curr;
curr.Next = temp;
if (curr.Next != null)
curr = curr.Next;
else
break;
if (curr.Next.Next!=null)
next = curr.Next.Next;
else
break;
}
}
Take a look at this C++ solution:
public void exchangeAdjElements(){
LLMain backup=current.next;
LLMain temp = current.next;
LLMain previous=current;
while(current!=null && current.next!=null){
previous.next=current.next;
current.next=temp.next;
temp.next=current;
if(current.next!=null){
previous=current;
current=current.next;
temp=current.next;
}
}
current=backup;
}
Here current is the head node.
Here's a rough sketch of a much simpler version, assuming Node has "Next" and "Data" members:
for (Node n = head; n && n.Next; n = n.Next.Next) {
void* tmp = n.Data;
n.Data = n.Next.Data;
n.Next.Data = tmp;
}
In other words, stop at every other node in the list and swap its data with the next one (the one). Simple.
Edit: Above solution swaps data within the nodes but not the nodes themselves. If you want to swap actual nodes, the solution requires more logic.
#dkamins: U are changing the values but in these type of questions, interviewers generally ask for pointer shuffling.
My attempt for the problem:
void swap (struct list **list1)
{
struct list *cur, *tmp, *next;
cur = *list1;
if(!cur || !cur->next)
return;
*list1 = cur->next;
while(cur && cur->next)
{
next = cur->next;
cur->next = next->next;
tmp = cur->next;
next->next = cur;
if(tmp && tmp->next)
cur->next = cur->next->next;
cur = tmp;
}
}
Here it is in complete runnable Java. This is purely pointer play.
public class ListSwap {
// the swap algorithm
static void swap(Node current) {
while (true) {
Node next1 = current.next;
if (next1 == null) break;
Node next2 = next1.next;
if (next2 == null) break;
Node next3 = next2.next;
current.next = next2;
next2.next = next1;
next1.next = next3;
current = next1;
}
}
// the rest is infrastructure for testing
static class Node {
Node next;
final char data; // final! Only pointer play allowed!
Node(char data, Node next) {
this.data = data;
this.next = next;
}
#Override public String toString() {
return data + (next != null ? next.toString() : "");
}
}
(continued...)
static class List {
Node head;
List(String data) {
head = null;
String dataReversed = new StringBuilder(data).reverse().toString();
for (char ch : dataReversed.toCharArray()) {
head = new Node(ch, head);
}
head = new Node('#', head);
}
#Override public String toString() {
return head.toString();
}
void swapPairs() {
swap(head);
}
}
public static void main(String[] args) {
String data = "a1b2c3d4e5";
for (int L = 0; L <= data.length(); L++) {
List list = new List(data.substring(0, L));
System.out.println(list);
list.swapPairs();
System.out.println(list);
}
}
}
(see full output)
I adapted #dkamins' solution, in a way. Instead of taking in a pointer to a pointer, I return the new head. I also beefed it up.
struct Node
{
struct Node *next;
int data;
};
typedef struct Node * NodePtr;
NodePtr swapEveryTwo(NodePtr head)
{
NodePtr newHead = (head && head->next) ? head->next : head;
NodePtr n = head;
while(n && n->next)
{
NodePtr tmp = n; // save (1)
n = n->next; // (1) = (2)
tmp->next = n->next; // point to the 3rd item
n->next = tmp; // (2) = saved (1)
n = tmp->next; // move to item 3
// important if there will be further swaps
if(n && n->next) tmp->next = n->next;
}
// return the new head
return newHead;
}
Basically, the new head of the list is either the current head if NULL or length 1, or the 2nd element.
In the swap loop, tmp will eventually become the 2nd element, but initially it is the first. We need it therefore to point to the 3rd element, which is the purpose of tmp->next = n->next;. I don't use a for loop because if we did, it is less intuitive - the reevaluation expression would only appear to be jumping by 1 node per iteration. At the end of the while loop, n = tmp->next; makes intuitive sense - we are pointing it to the element after tmp, the 2nd element.
The most important part is the last line. Because we are doing this in a forward direction, we have to remember that the previous iteration's 2nd element is almost certainly going to be pointing to the current iteration's eventual 4th element, because this iteration will swap 3 and 4. So at the end of the iteration, if we realize we are going to swap again next iteration, we quietly point the 2nd element to the current 4th element, knowing that next iteration it will be the 3rd element and all is right in the world.
For example, if the list is 2 -> 7 -> 3 -> 5:
n = 2
tmp = 2
n = 7
tmp->next = 3 (2 -> 3)
n->next = 2 (7 -> 2)
n = 3
7 -> 2 -> 3 -> 5
but then there will be swaps, so the last statement says
7 -> 2 -> 5 3?
This is ok because n = 3, so we haven't lost that node. Next iteration:
n = 3
tmp = 3
n = 5
tmp->next = NULL (3 -> NULL)
n->next = 3 (5 -> 3)
n = NULL
Leading to the final 7 -> 2 -> 5 -> 3 answer.
I guess to make it more efficient, it would be better to take another argument n in the function.
This n is used for count , i.e after how much count the nodes needs to be changed. in above case n= 2.
And then keep on iterating until you hit the n and used the reverse linklist alog or recursive reverse linklist algo to do it.
void ReverseLinkList(struct node* head, int n)
{
if( head == null || null <= 0)
return;
struct node* start = head;
struct node* next = null;
struct node* end = head;
int count = 1;
while(end->next != null)
{
if(count == n)
{
next = end->next;
count = 1;
//Use ReverseLinklist From start to end
end->next = next;
end = next;
start = next;
}
else
{
end = end->next;
count++;
}
}
}
void SwapAdjacentNodes (Node head)
{
if (head == null) return;
if (head.next == null) return;
Node curr = head;
Node next = curr.Next;
Node temp = next.Next;
while (true)
{
temp = next.Next;
next.Next = curr;
curr.Next = temp;
if (curr.Next != null)
curr = curr.Next;
else
break;
if (curr.Next.Next!=null)
next = curr.Next.Next;
else
break;
}
}
Does it work!?
Because.
say :
1[cur] -> 2[next] -> 3 [temp]-> 4
After the loop
2 -> 1 -> 3[cur] -> 4[next] -> NULL [temp]
and then.
2 -> 1 -> 4 -> 3 -> NULL
That is what we expect right?
But u know. The real thing will be like.
2 -> (1,4) -> 3 -> NULL
Because u didn't change the 1->next link to 4! It still points to 3!
MY VERSION : Click here
here's my c++ code : it will return the pointer to the swapped linked list
Node* swap_list(Node* node) {
if(node == NULL)
return NULL;
Node* ret = node->next;
Node* pre_a = NULL;
Node* a = node;
Node* b = node->next;
while(a!=NULL && b!=NULL) {
a->next = b->next;
b->next = a;
if(pre_a!=NULL)
pre_a->next = b;
pre_a = a;
a = a->next;
if(a==NULL) break;
b = a->next;
}
return ret;
}
private static SList swapAlternateElements(SList n){
if(n == null)
return n;
SList head = swap(n);
SList tail = head;
while(tail == null || tail.next != null){
tail.next.next = swap(tail.next.next);
tail = tail.next.next;
}
return head;
}
private static SList swap(SList n){
if(n.next == null || n==null){
return n;
}
SList current = n.next;
SList next = current.next;
n.next = next;
current.next = n;
return current;
}
I tried to solve it and here is the solution.
public Node swapAdjacentNodes() {
if (head == null)
return null;
if (head.nextNode == null)
return head;
Node previous = null;
Node current = head;
Node next = head.nextNode;
while (next != null && next != current) {
current.nextNode = next.nextNode;
next.nextNode = current;
if (previous == null) {
previous = next;
head = previous;
previous = previous.nextNode;
} else {
previous.nextNode = next;
previous = previous.nextNode.nextNode;
}
current = current.nextNode;
if (current == null)
break;
next = next.nextNode.nextNode.nextNode;
}
return head;
}
Here is my C function to swap links of alternate nodes in linked list.I have included comments in the code. For better understanding take an example and run through the steps by making diagrams using pen and paper.
void swap_alternate_nodes(struct node **head)
{
if(*head==NULL)
return;
if((*head)->next==NULL)
return;
struct node *prev = *head;
struct node *curr = (*head)->next;
struct node *temp = NULL;
*head = (*head)->next; // new head will be second node
while(curr!=NULL && prev!=NULL)
{
if(temp!=NULL)
temp->next = curr; // previous prev node pointer should point to curr pointer
prev->next = curr->next; // update prev node pointer
curr->next = prev; // update curr node pointer
temp = prev; //store prev pointer
prev = prev->next; // forward prev pointer
if(prev)
curr = prev->next; // forward curr pointer
}
}
My take on the solution:-
public Node exchangeAdjacentNodes(Node head){
Node curr = head;
Node temp=null,next=null;
if(curr==null||curr.next==null){
return curr;
Node head = curr.next;
while(curr!=null && curr.next!=null){
next = curr.next;
curr.next=next.next;
temp = curr.next;
next.next = curr;
if(temp!=null && temp.next!=null)
curr.next = curr.next.next;
curr=temp;
}
return head;
}
Here, 'head' is the pointer to the first node of the Linked-List and the function returns the new head pointer.
node* swapPairs(node *head) {
if(head==NULL || head->next==NULL) {
return head;
}
node *ptr1=head->next;
node *ptr2=ptr1->next;
ptr1->next=head;
head->next=swapPairs(ptr2);
return ptr1;
}
public void swapAdjacent() {
temp = head;
while (temp != null && temp.next != null) {
Object tem = temp.val;
temp.val = temp.next.val;
temp.next.val = (Object) tem;
temp = temp.next.next;
}
}
It might help :
public static void main(String[] args) {
String arr[] = { "a", "b", "c", "d", "e", "f" };
int i = 0;
int k = 1;
String temp;
while (k <= arr.length - 1 && arr[i] != null && arr[k] != null) {
temp = arr[i];
arr[i] = arr[k];
arr[k] = temp;
k++;
i = k;
k++;
}
for (int j = 0; j < arr.length; j++) {
System.out.print(arr[j]+"->");
}
}
// Input -> a->b->c->d->e->f->
// Output -> b->a->d->c->f->e->
C Code to swap Adjacent
node *SwapAdjacent(node *root)
{
*NextNode = NULL;
node * result = root->next;
node *prev = NULL;
while (root != NULL && root->next!=NULL)
{
if(prev!=NULL)
prev->next= root->next;
NextNode = root->next->next;
root->next->next = root;
root->next = NextNode;
prev = root;
root = NextNode;
}
return result;
}

Resources