merge sort linkedlist - stackoverflow error - recursion

I am trying to solve leetcode-148 (https://leetcode.com/problems/sort-list/) i.e. sort given LinkedList, but am getting a stackoverflow error. so far I have tried dry running but am not seeing where the issue could occur.. the base condition of the recursion seems to be right but looks like I am missing something if someone sees what I am not seeing..
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode sortList(ListNode head) {
if (head==null || head.next==null) return head;
ListNode follow = new ListNode(0);
follow.next=head;
ListNode fast = head;
ListNode slow = head;
// Find the mid-point of the list
while (fast.next!=null && fast.next.next!=null) {
slow=slow.next;
fast=fast.next.next;
follow=follow.next;
}
// Split the list
follow.next = null;
// Sort each half
ListNode first = sortList(head);
ListNode second = sortList(slow);
// Merge
return merge(first, second);
}
private ListNode merge(ListNode first, ListNode second) {
if (first==null) return second;
if (second==null) return first;
ListNode result = new ListNode(0);
ListNode head = result;
while (first!=null && second!=null) {
if (first.val<second.val) {
result.next = first;
} else {
result.next = second;
}
result=result.next;
}
if (first!=null) {
result.next = first;
result=result.next;
}
if (second!=null) {
result.next = second;
result=result.next;
}
return head.next;
}
}
Here's the error
WARNING: A command line option has enabled the Security Manager
WARNING: The Security Manager is deprecated and will be removed in a future release
java.lang.StackOverflowError
at line 31, Solution.sortList
at line 31, Solution.sortList
at line 31, Solution.sortList
at line 31, Solution.sortList
at line 31, Solution.sortList

There are two issues:
When sortList is called with a list that has 2 nodes, then after the first loop (which makes no iterations), slow will be equal to head, and follow.next = null will just mutate the dummy node that was prepended before the head node. So essentially the linked list wasn't split, and the recursive call is on the same list, leading to infinite recursion. Solve this by changing the while condition so at least one iteration will be made. Also, you can do this without a third reference (follow).
In merge, the first and second references do not move forward, so the loop will be infinite.
Here is corrected code:
public ListNode sortList(ListNode head) {
if (head == null || head.next == null) return head;
ListNode fast = head.next;
ListNode slow = head;
// Find the mid-point of the list
while (fast != null && fast.next != null) { // iterate at least once
slow = slow.next;
fast = fast.next.next;
}
// Split the list
ListNode second = slow.next;
slow.next = null;
// Sort each half
head = sortList(head);
second = sortList(second);
// Merge
return merge(head, second);
}
private ListNode merge(ListNode first, ListNode second) {
ListNode result = new ListNode(0);
ListNode head = result;
while (first != null && second != null) {
if (first.val < second.val) {
result.next = first;
first = first.next; // move forward
} else {
result.next = second;
second = second.next;
}
result = result.next;
}
if (first != null) {
result.next = first;
result = result.next;
}
if (second != null) {
result.next = second;
result = result.next;
}
return head.next;
}

Related

Is there a way to modify the value inside a self referential structure using another pointer

Is there any way to store the value of the pointer inside a self-referential structure and then use it to modify the pointer instead of the structure it points to?
I'm trying to perform bst deletion using the following code:
struct node *temp = start;
struct node *parent = start;
int isRight = 0, flag = 0;
while(temp != NULL)
{
if(temp->data == key)
{
if(isRight == 1)
parent = parent->rlink;
else
parent = parent->llink;
if(temp->rlink != NULL)
{
if(temp->llink != NULL)
{
replace(temp->llink, temp->rlink);
}
parent = temp->rlink;
}
else if(temp->llink != NULL)
{
parent = temp->llink;
}
else
{
parent = NULL;
}
flag = 1;
break;
}
else if(temp->data < key)
{
parent = temp;
isRight = 1;
temp = temp->rlink;
}
else
{
parent = temp;
isRight = 0;
temp = temp->llink;
}
}
where:
void replace(struct node *temp, struct node *root)
{
while(root->llink != NULL)
{
root = root->llink;
}
root->llink = temp;
}
The problem is that parent = parent->llink/rlink just makes it so that the pointer parent points to the node that is in the parent->llink part of the node.
Is there any way to rewrite this code so that I can make the parent refer to the memory location inside the node parent which stores the link to the next node instead of the node itself?
I can rewrite this code to assign values directly to parent->llink/rlink by checking isRight for each case, but the code looks too clunky.
(This is not the actual way to perform bst deletion, but I'm trying to solve this on a whim.)

K-th largest element in BST

I am trying to find the K-th largest element in a Binary Search Tree using reverse inorder approach by using a counter. Here is what I have implemented:
int klargest(Node root,int k,int count)
{
if(root != null)
{
klargest(root.right,k,count);
count++;
if(count == k)
return root.data;
klargest(root.left,k,count);
}
return -1;
}
But the issue is that when count = k, the code does not return the answer to the caller function but instead to a sub-call. Due to this, the answer is lost. In other words, the recursion does not stop there and it keeps on going until all the nodes are visited. In the end, I get the answer -1. What I want is that the recursion should end when count = k and the required answer should be returned to the caller function. How can I do this?
Note: I neither want to use a global variable nor an iterative approach.
Actually, you do not return your node - the recursive call results are ignored. Rewrite it so it returns a Node:
Node klargest(Node root,int k,int count)
{
Node result = null;
if(root != null)
{
result = klargest(root.right,k,count);
if (result != null)
return result;
count++;
if(count == k)
return root;
result = klargest(root.left,k,count);
}
return result;
}
You can use this approach:
int kthLargest(Node node, int k) {
int rightCount = count(node.right);
if (k <= rightCount) {
return kthLargest(node.right, k);
} else if (k == rightCount+1) {
return node.data;
} else {
return kthLargest(node.left, k - rightCount + 1);
}
}
int count(Node node) {
if (node != null) {
return count(node.left) + count(node.right) + 1;
}
return 0;
}

Count the number of nodes of a doubly linked list using recursion

Here is what I've done so far:
struct rep_list {
struct node *head;
struct node *tail;
}
typedef rep_list *list;
int length(const list lst) {
if (lst->head == NULL) {
return 0;
}
else {
lst->head = lst->head->next;
return 1 + length(lst);
}
}
This works, but the head of the list the function accepts as a parameter gets changed. I don't know how to fix that.
I'm not allowed to change the function definition so it should always accept a list variable.
Any ideas?
EDIT: I tried to do what Tyler S suggested in the comments but I encountered another problem. If I create a node* variable at the beginning, it should point to lst->head. But then every recursive call to the function changes the value back to lst->head and I cannot move forward.
You don't need a local node: just don't change the list head. Instead, pass the next pointer as the recursion head.
int length(const list lst) {
if (lst->head == NULL) {
return 0;
}
else {
return 1 + length(lst->head-next);
}
}
I see. Okay; this gets a bit clunky because of the chosen representation. You need a temporary variable to contain the remaining list. This iscludes changing the head.
int length(const list lst) {
if (lst->head == NULL) {
return 0;
}
else {
new_lst = new(list)
new_lst->head = lst->head->next;
var result = 1 + length(new_lst);
free(new_lst)
return result
}
}
At each recursion step, you create a new list object, point it to the 2nd element of the current list, and continue. Does this do the job for you?
Although this solution is clunky and I hate it, its the only way I can see to accomplish what you're asking without modifying the method signature. We create a temporary node * as member data of the class and modify it when we start.
struct rep_list {
struct node *head;
struct node *tail;
}
node *temp = NULL;
bool didSetHead = false;
typedef rep_list *list;
int length(const list lst) {
if ((didSetHead) && (lst->head != temp)) {
temp = lst->head;
didSetHead = false;
}
if (temp == NULL) {
didSetHead = true;
return 0;
}
else {
temp = temp->next;
return 1 + length(temp);
}
}
Please note, I haven't tested this code and you may have to play with a bit, but the idea will work.

Reverse Linked List recursively, why it is wrong

Problem: Reverse a singly linked list recursively.
I know how to solve this problem, but one of my recursive methods is wrong, I can not figure out what's wrong with this code. Could anyone figure out that? Thanks a lot!
Test case:
Input:
[1,2,3]
Output:
[3,1]
Expected:
[3,2,1]
public class Solution {
// recursive
ListNode last = null;
public ListNode reverseList(ListNode head) {
if (head == null) return null;
helper(head);
return last;
}
private ListNode helper(ListNode head) {
// base case
if (head.next == null) {
last = head;
return head;
}
// general case
ListNode prev = reverseList(head.next); // should be ListNode prev = helper(head.next);
prev.next = head;
head.next = null;
return head;
}
}
It doesn't work, because in the first pass of the helper method
ListNode prev = reverseList(head.next);
returns [3, 2], and then you assign your old head (1) to be the next node after the new head of the reversed list (3). Therefore, the end result is [3, 1].

Is it possible to use a Kleene Operator for Flex Formatters?

is it possible to use a Kleene Operator (Kleene Star) for the Formatters?
I want to use a phoneFormatter, which puts a minus after the 5th number and afterwards it should be possible to have a variable number of numbers.
E.g.: 0172-555666999, 0160-44552 etc.
That is how I started, but I don't know which character belongs after the last hash (it is not a star, I already tried it ;-) ):
<fx:Declarations>
<mx:PhoneFormatter id="mPhoneFormat"
formatString="####-#"/>
</fx:Declarations>
The default PhoneFormatter expects the input string to have the same number of characters as the format string. They don't support regular expression patterns (like * to match the element zero or more times).
However, it's pretty easy to make your own formatter. To do this, I extended the PhoneFormatter class and overrode its format() method. I copied and pasted the original format() method and made the following modifications:
comment out the code that compared the length of the source string with the length of the format string
compare the length of the formatted string. If the original string is longer, append the remaining chars from the original string to the formatted string.
This probably won't handle all of your use cases, but it should be pretty straightforward to modify this to your needs.
package
{
import mx.formatters.PhoneFormatter;
import mx.formatters.SwitchSymbolFormatter;
public class CustomPhoneNumberFormatter extends PhoneFormatter
{
public function CustomPhoneNumberFormatter()
{
super();
}
override public function format(value:Object):String
{
// Reset any previous errors.
if (error)
error = null;
// --value--
if (!value || String(value).length == 0 || isNaN(Number(value)))
{
error = defaultInvalidValueError;
return "";
}
// --length--
var fStrLen:int = 0;
var letter:String;
var n:int;
var i:int;
n = formatString.length;
for (i = 0; i < n; i++)
{
letter = formatString.charAt(i);
if (letter == "#")
{
fStrLen++;
}
else if (validPatternChars.indexOf(letter) == -1)
{
error = defaultInvalidFormatError;
return "";
}
}
// if (String(value).length != fStrLen)
// {
// error = defaultInvalidValueError;
// return "";
// }
// --format--
var fStr:String = formatString;
if (fStrLen == 7 && areaCode != -1)
{
var aCodeLen:int = 0;
n = areaCodeFormat.length;
for (i = 0; i < n; i++)
{
if (areaCodeFormat.charAt(i) == "#")
aCodeLen++;
}
if (aCodeLen == 3 && String(areaCode).length == 3)
{
fStr = String(areaCodeFormat).concat(fStr);
value = String(areaCode).concat(value);
}
}
var dataFormatter:SwitchSymbolFormatter = new SwitchSymbolFormatter();
var source:String = String(value);
var returnValue:String = dataFormatter.formatValue(fStr, value);
if (source.length > returnValue.length)
{
returnValue = returnValue + source.substr(returnValue.length-1);
}
return returnValue;
}
}
}

Resources