Given a linked list, reverse the second half linked list. If the list length is odd, then the middle list node also should be reversed.
For example:
Given: 1 -> 2 -> 3 -> null;
Return: 1 -> 3 -> 2 -> null;
Given: 1 -> 2 -> 3 -> 4 -> null;
Return: 1 -> 2 -> 4 -> 3 -> null;
/*
First compute the size of list to determine the middle list node.
time:O(n), space:O(1)
*/
import java.util.*;
class ListNode {
int val;
ListNode next;
public ListNode(int val) {
this.val = val;
next = null;
}
}
public class Solution {
public static ListNode reverseHalfList(ListNode head) {
if (head == null || head.next == null) {
return head;
}
int size = calSize(head);
ListNode middle = getMidNode(head, size);
middle.next = reverse(middle.next);
return head;
}
public static int calSize(ListNode head) {
int size = 0;
while (head != null) {
head = head.next;
size++;
}
return size;
}
public static ListNode getMidNode(ListNode head, int size) {
ListNode dummy = new ListNode(-1);
dummy.next = head;
ListNode slow = (size & 1) == 0 ? head : dummy;
ListNode fast = head.next;
while (fast != null && fast.next != null) {
slow = slow.next;
fast = fast.next.next;
}
return slow;
}
public static ListNode reverse(ListNode head) {
ListNode newHead = null;
while (head != null) {
ListNode temp = head.next;
head.next = newHead;
newHead = head;
head = temp;
}
return newHead;
}
public static void main(String[] args) {
ListNode n1 = new ListNode (1);
ListNode n2 = new ListNode (2);
ListNode n3 = new ListNode (3);
ListNode n4 = new ListNode (4);
ListNode n5 = new ListNode (5);
ListNode n6 = new ListNode (6);
ListNode n7 = new ListNode (7);
n1.next = n2;
n2.next = n3;
n3.next = n4;
n5.next = n6;
n6.next = n7;
ListNode ans1 = reverseHalfList(n1);
ListNode ans2 = reverseHalfList(n5);
while (ans1 != null) {
System.out.print(ans1.val + " ");
ans1 = ans1.next;
}
System.out.println(" ");
while (ans2 != null) {
System.out.print(ans2.val + " ");
ans2 = ans2.next;
}
}
}
Showing posts with label linked list. Show all posts
Showing posts with label linked list. Show all posts
Monday, January 16, 2017
Sunday, January 15, 2017
LRU Cache Miss
Implement LRU cache, and count the miss number which is not in the cache before added to the cache.
import java.util.*;
class ListNode {
int key;
ListNode prev, next;
public ListNode(int key) {
this.key = key;
prev = next = null;
}
}
public class Solution {
public static int cacheMiss(int[] array, int size) {
if (array == null || array.length == 0 || size <= 0) {
return 0;
}
Map<Integer, ListNode> cache = new HashMap<>();
ListNode head = new ListNode(-1);
ListNode tail = new ListNode(-1);
head.next = tail;
tail.prev = head;
int count = 0;
for (int i = 0; i < array.length; i++) {
ListNode newNode = new ListNode(array[i]);
if (!cache.containsKey(array[i])) {
if (cache.size() == size) {
cache.remove(head.next.key);
head.next = head.next.next;
head.next.prev = head;
}
count++;
} else {
ListNode node = cache.get(array[i]);
node.prev.next = node.next;
node.next.prev = node.prev;
}
newNode.prev = tail.prev;
newNode.next = tail;
tail.prev = newNode;
newNode.prev.next = newNode;
cache.put(array[i], newNode);
}
return count;
}
public static void main(String[] args) {
int[] A = {1,2,3,1,4,3};
int res = cacheMiss(A, 3);
System.out.println(res);
}
}
import java.util.*;
class ListNode {
int key;
ListNode prev, next;
public ListNode(int key) {
this.key = key;
prev = next = null;
}
}
public class Solution {
public static int cacheMiss(int[] array, int size) {
if (array == null || array.length == 0 || size <= 0) {
return 0;
}
Map<Integer, ListNode> cache = new HashMap<>();
ListNode head = new ListNode(-1);
ListNode tail = new ListNode(-1);
head.next = tail;
tail.prev = head;
int count = 0;
for (int i = 0; i < array.length; i++) {
ListNode newNode = new ListNode(array[i]);
if (!cache.containsKey(array[i])) {
if (cache.size() == size) {
cache.remove(head.next.key);
head.next = head.next.next;
head.next.prev = head;
}
count++;
} else {
ListNode node = cache.get(array[i]);
node.prev.next = node.next;
node.next.prev = node.prev;
}
newNode.prev = tail.prev;
newNode.next = tail;
tail.prev = newNode;
newNode.prev.next = newNode;
cache.put(array[i], newNode);
}
return count;
}
public static void main(String[] args) {
int[] A = {1,2,3,1,4,3};
int res = cacheMiss(A, 3);
System.out.println(res);
}
}
LRU Cache
Design and implement a data structure for Least Recently Used (LRU) cache. It should support the following operations:
get and set.get(key) - Get the value (will always be positive) of the key if the key exists in the cache, otherwise return -1.set(key, value) - Set or insert the value if the key is not already present. When the cache reached its capacity, it should invalidate the least recently used item before inserting a new item.
/*
LinkedHashMap = DoublyLinkedList + HashMap.
Newest node append to tail and eldest node remove from head.
Notice:
1. When use DoublyLinkedList, ListNode head and tail should be initialized at first.
2. In the ListNode, key should be added.
*/
public class Solution {
private class ListNode {
ListNode prev;
ListNode next;
int key;
int value;
public ListNode(int key, int value) {
this.key = key;
this.value = value;
prev = null;
next = null;
}
}
private int capacity;
private Map<Integer, ListNode> map = new HashMap<>();
private ListNode head = new ListNode(-1, -1);
private ListNode tail = new ListNode(-1, -1);
public Solution(int capacity) {
this.capacity = capacity;
head.next = tail;
tail.prev = head;
}
public int get(int key) {
if (!map.containsKey(key)) {
return -1;
}
ListNode temp = map.get(key);
temp.prev.next = temp.next;
temp.next.prev = temp.prev;
moveToTail(temp);
return map.get(key).value;
}
public void set(int key, int value) {
if (get(key) != -1) {
map.get(key).value = value;
return;
}
if (map.size() == capacity) {
//This is why key should be added to the ListNode.
map.remove(head.next.key);
head.next = head.next.next;
head.next.prev = head;
}
ListNode node = new ListNode(key, value);
map.put(key, node);
moveToTail(node);
}
private void moveToTail(ListNode node) {
node.prev = tail.prev;
node.next = tail;
tail.prev = node;
node.prev.next = node;
}
}
Linked List Cycle II
Given a linked list, return the node where the cycle begins.
If there is no cycle, return
null.
For example:
Given
-21->10->4->5, tail connects to node index 1,return 10/**
* Definition for ListNode.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int val) {
* this.val = val;
* this.next = null;
* }
* }
*/
/*
time:O(n), space:O(1)
*/
public class Solution {
public ListNode detectCycle(ListNode head) {
if (head == null) {
return head;
}
ListNode slow = head;
ListNode fast = head.next;
while (slow != fast) {
if (fast == null || fast.next == null) {
return null;
}
slow = slow.next;
fast = fast.next.next;
}
while (head != slow.next) {
head = head.next;
slow = slow.next;
}
return head;
}
}
Insert into Cycle Linked List
Insert a new list node into a sorted cycle linked list.
/*
time:O(n), space:O(1)
*/
import java.util.*;
class ListNode {
int val;
ListNode next;
public ListNode(int val) {
this.val = val;
next = null;
}
}
public class Solution {
public static ListNode insertCycleLinkedList(ListNode head,
int val) {
ListNode curr = new ListNode(val);
if (head == null) {
curr.next = curr;
return curr;
}
ListNode node = head;
do {
if (val >= node.val && val <= node.next.val) {
break;
}
if (node.val >= node.next.val &&
(val >= node.val || val <= node.next.val)) {
break;
}
node = node.next;
} while (node != head);
curr.next = node.next;
node.next = curr;
return curr;
}
public static void main(String[] args) {
ListNode n1 = new ListNode (1);
ListNode n2 = new ListNode (1);
ListNode n3 = new ListNode (1);
n1.next = n2;
n2.next = n3;
n3.next = n1;
ListNode ans = insertCycleLinkedList(n1, 2);
ListNode tmp = ans;
do {
System.out.print(tmp.val + " ");
tmp = tmp.next;
} while (tmp != ans);
}
}
/*
time:O(n), space:O(1)
*/
import java.util.*;
class ListNode {
int val;
ListNode next;
public ListNode(int val) {
this.val = val;
next = null;
}
}
public class Solution {
public static ListNode insertCycleLinkedList(ListNode head,
int val) {
ListNode curr = new ListNode(val);
if (head == null) {
curr.next = curr;
return curr;
}
ListNode node = head;
do {
if (val >= node.val && val <= node.next.val) {
break;
}
if (node.val >= node.next.val &&
(val >= node.val || val <= node.next.val)) {
break;
}
node = node.next;
} while (node != head);
curr.next = node.next;
node.next = curr;
return curr;
}
public static void main(String[] args) {
ListNode n1 = new ListNode (1);
ListNode n2 = new ListNode (1);
ListNode n3 = new ListNode (1);
n1.next = n2;
n2.next = n3;
n3.next = n1;
ListNode ans = insertCycleLinkedList(n1, 2);
ListNode tmp = ans;
do {
System.out.print(tmp.val + " ");
tmp = tmp.next;
} while (tmp != ans);
}
}
Saturday, January 14, 2017
Merge Two Sorted Lists
Merge two sorted linked lists and return it as a new list. The new list should be made by splicing together the nodes of the first two lists.
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
/*
time:O(n), space:O(1)
*/
public class Solution {
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
if (l1 == null) {
return l2;
}
if (l2 == null) {
return l1;
}
ListNode dummy = new ListNode(0);
ListNode curr = dummy;
while (l1 != null && l2 != null) {
if (l1.val < l2.val) {
curr.next = l1;
l1 = l1.next;
} else {
curr.next = l2;
l2 = l2.next;
}
curr = curr.next;
}
if (l1 != null) {
curr.next = l1;
}
if (l2 != null) {
curr.next = l2;
}
return dummy.next;
}
}
Sunday, January 8, 2017
Merge k Sorted Lists
Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity.
Example
Given lists:
[
2->4->null,
null,
-1->null
],
return
-1->2->4->null./**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
/*
First put all the ListNode in the input array into the min-heap. Every time, pop out the ListNode with the smallest value. If this ListNode's next node is not null, then push the next ListNode into the min-heap.
PriorityQueue. time: O(NlogK), space: O(K), N: the number of all the ListNode,K: the length of the input lists array.
*/
public class Solution {
private Comparator<ListNode> ListNodeComparator = new Comparator<ListNode>() {
public int compare(ListNode a, ListNode b) {
return a.val - b.val; //b.val-a.val, descending sort.
}
};
public ListNode mergeKLists(ListNode[] lists) {
if (lists == null || lists.length == 0) {
return null;
}
Queue<ListNode> heap = new PriorityQueue<>(lists.length, ListNodeComparator);
for (ListNode node : lists) {
if (node != null) {
heap.offer(node);
}
}
ListNode dummy = new ListNode(0);
ListNode tail = dummy;
while (!heap.isEmpty()) {
ListNode head = heap.poll();
tail.next = head;
tail = head;
if (head.next != null) {
heap.offer(head.next);
}
}
return dummy.next;
}
}
//divide & conquer, recursion, time: O(NlogK), space: O(1)
public class Solution {
public ListNode mergeKLists(ListNode[] lists) {
if (lists == null || lists.length == 0) {
return null;
}
return mergeHelper(lists, 0, lists.length - 1);
}
public ListNode mergeHelper(ListNode[] lists, int start, int end) {
if (start == end) {
return lists[start];
}
int mid = start + (end - start) / 2;
ListNode left = mergeHelper(lists, start, mid);
ListNode right = mergeHelper(lists, mid + 1, end);
return mergeTwoLists(left, right);
}
private ListNode mergeTwoLists(ListNode head1, ListNode head2) {
ListNode dummy = new ListNode(0);
ListNode temp = dummy;
while (head1 != null && head2 != null) {
if (head1.val < head2.val) {
temp.next = head1;
head1 = head1.next;
} else {
temp.next = head2;
head2 = head2.next;
}
temp = temp.next;
}
if (head1 != null) {
temp.next = head1;
} else {
temp.next = head2;
}
return dummy.next;
}
}
//merge two by two, iteration, time: O(NlogK), space: O(K)
public class Solution {
private ListNode mergeTwoLists(ListNode head1, ListNode head2) {
ListNode dummy = new ListNode(0);
ListNode temp = dummy;
while (head1 != null && head2 != null) {
if (head1.val < head2.val) {
temp.next = head1;
head1 = head1.next;
} else {
temp.next = head2;
head2 = head2.next;
}
temp = temp.next;
}
if (head1 != null) {
temp.next = head1;
} else {
temp.next = head2;
}
return dummy.next;
}
public ListNode mergeKLists(ListNode[] lists) {
if (lists == null || lists.length == 0) {
return null;
}
int index = 0;
while (lists.length > 1) {
int l = lists.length;
ListNode[] newList = new ListNode[(l + 1) / 2];
for (int i = 0; i + 1 < l; i += 2) {
ListNode temp = mergeTwoLists(lists[i],
lists[i + 1]);
newList[index++] = temp;
}
if (l % 2 == 1) {
newList[index] = lists[l - 1];
}
lists = newList;
index = 0;
}
return lists[0];
}
}
//merge two by two, iteration, time: O(NlogK), space: O(1)
public class Solution {
private ListNode mergeTwoLists(ListNode head1, ListNode head2) {
ListNode dummy = new ListNode(0);
ListNode temp = dummy;
while (head1 != null && head2 != null) {
if (head1.val < head2.val) {
temp.next = head1;
head1 = head1.next;
} else {
temp.next = head2;
head2 = head2.next;
}
temp = temp.next;
}
if (head1 != null) {
temp.next = head1;
} else {
temp.next = head2;
}
return dummy.next;
}
public ListNode mergeKLists(ListNode[] lists) {
if (lists == null || lists.length == 0) {
return null;
}
int size = lists.length;
while (size > 1) {
for (int i = 0, j = size - 1; i < j; i++, j--) {
lists[i] = mergeTwoLists(lists[i], lists[j]);
}
size = (size + 1) / 2;
}
return lists[0];
}
}
Saturday, January 7, 2017
Reverse Linked List
Reverse a singly linked list.
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
/*First initialize a pointer 'newHead' pointing to null. In each iteration, we do four steps.
1. New a 'tmp' pointer pointing to 'head.next';
2. Let 'head.next' connect to 'newHead';
3. Let 'newHead' point to 'head';
4. Let 'head' point to 'tmp'.
time: O(n), space:O(1)
*/
public class Solution {
public ListNode reverseList(ListNode head) {
if (head == null) {
return head;
}
ListNode newHead = null;
while (head != null) {
ListNode tmp = head.next;
head.next = newHead;
newHead = head;
head = tmp;
}
return newHead;
}
}
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
/*First initialize a pointer 'newHead' pointing to null. In each iteration, we do four steps.
1. New a 'tmp' pointer pointing to 'head.next';
2. Let 'head.next' connect to 'newHead';
3. Let 'newHead' point to 'head';
4. Let 'head' point to 'tmp'.
time: O(n), space:O(1)
*/
public class Solution {
public ListNode reverseList(ListNode head) {
if (head == null) {
return head;
}
ListNode newHead = null;
while (head != null) {
ListNode tmp = head.next;
head.next = newHead;
newHead = head;
head = tmp;
}
return newHead;
}
}
Subscribe to:
Posts (Atom)