Finding and removing the last occurrence of an element in a (singly) linked list with only one traversal - data-structures

Is it possible to find the last occurrence of an element (for example, an integer) and remove this node with only one (forward) traversal through the list?

Yes.
Simply remember the previous entry every time you find the value you're searching for on the traversal. When the traversal is complete, the last entry remembered will have a link to the entry to be removed, and that is sufficient to do the removal.

public void DeleteLastOccurenceOfKey(Node head, int key)
{
Node current=head;
Node prev=null;
Node temp=null;
while(current!=null)
{
if(current.next!=null && current.next.data==key)
{
prev=current;
temp=current.next;
}
current=current.next;
}
prev.next=temp.next;
}
DeleteLastOccurenceOfKey(head,25);
I/P:5 10 15 25 35 25 40
O/P:5 10 15 25 35 40

/*
* Delete last occurrence of an item from linked list
* Given a liked list and a key to be deleted. Delete last occurrence of key
* from linked. The list may have duplicates.
*
* Examples:
*
* Input: 1->2->3->5->2->10, key = 2`enter code here`
* Output: 1->2->3->5->10
*/
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
typedef struct list_ list;
struct list_ {
int d;
list *next;
};
void insert (list **head, int d) {
list *tmp = (list *)malloc(sizeof(list));
assert(tmp);
tmp->d = d;
tmp->next = *head;
*head = tmp;
}
void printL (list *p) {
while (p) {
printf (" %d ", p->d);
p = p->next;
}
printf ("\n");
}
void deletlastOccurence (list **head, int d) {
list *cur = *head;
list *prev = NULL;
list *match = NULL;
if (cur == NULL) {
printf ("list is empty\n");
return;
}
/*
* Special case when there only ONE NODE
* in the LIST
*/
if (cur->next == NULL) {
if (cur->d == d) {
printf ("Deleted one node %d\n", cur->d);
free(cur);
*head = NULL;
} else {
printf(" No match\n");
}
return;
}
/*
* Keep track of previous node
*/
while (cur && cur->next) {
if (cur->next->d == d) {
prev = cur;
match = cur->next;
}
cur = cur->next;
}
if (prev){
prev->next = match->next;
printf ("Delete %d\n", match->d);
free (match);
} else {
/*
* Special case when the last node is
* on the head itself
*/
if ((*head)->d == d) {
cur = *head;
*head = cur->next;
printf("element is at head Delete %d\n", cur->d);
free (cur);
} else {
printf ("No match\n");
}
}
printL(*head);
}
int main (int argc , char *argv) {
list *h = NULL;
insert(&h, 1);
insert(&h, 2);
insert(&h, 3);
insert(&h, 4);
insert(&h, 5);
insert(&h, 2);
insert(&h, 1);
insert(&h, 6);
printL(h);
deletlastOccurence(&h, 6);
deletlastOccurence(&h, 2);
}

public void deleteLastOccurence(int value) {
Element cur = this.head;
Element prev = null;
Element tmp = null;
if(this.head == null)
return;
if(this.head.data == value) {
this.head = null;
return;
}
while(cur != null) {
if(cur.next != null && cur.next.data == value) {
prev = cur;
tmp = cur.next;
}
cur = cur.next;
}
prev.next = tmp.next;
}

Related

Sub-sequence of Vowels

I was practicing for an interview and came across this question on a website:
A magical sub-sequence of a string S is a sub-sequence of S that
contains all five vowels in order. Find the length of largest magical sub-sequence of a string S.
For example, if S = aeeiooua, then aeiou and aeeioou are magical sub-sequences
but aeio and aeeioua are not.
I am a beginner in dynamic programming and am finding it hard to come up with a recursive formula for this.
I did it with an iterative approach rather than recursive one. I started building solution similar to LIS (Longest Increasing Subsequence) and then optimised it upto O(n).
#include<iostream>
#include<string>
#include<vector>
using namespace std;
string vowel = "aeiou";
int vpos(char c)
{
for (int i = 0; i < 5; ++i)
if (c == vowel[i])
return i;
return -1;
}
int magical(string s)
{
int l = s.length();
int previndex[5] = {-1, -1, -1, -1, -1}; // for each vowel
vector<int> len (l, 0);
int i = 0, maxlen = 0;
// finding first 'a'
while (s[i] != 'a')
{
++i;
if (i == l)
return 0;
}
previndex[0] = i; //prev index of 'a'
len[i] = 1;
for ( ++i; i < l; ++i)
{
if (vpos(s[i]) >= 0) // a vowel
{
/* Need to append to longest subsequence on its left, only for this vowel (for any vowels) and
* its previous vowel (if it is not 'a')
This important observation makes it O(n) -- differnet from typical LIS
*/
if (previndex[vpos(s[i])] >= 0)
len[i] = 1+len[previndex[vpos(s[i])]];
previndex[vpos(s[i])] = i;
if (s[i] != 'a')
{
if (previndex[vpos(s[i])-1] >= 0)
len[i] = max(len[i], 1+len[previndex[vpos(s[i])-1]]);
}
maxlen = max(maxlen, len[i]);
}
}
return maxlen;
}
int main()
{
string s = "aaejkioou";
cout << magical(s);
return 0;
}
O(input string length) runtime
import java.util.*;
public class Main {
/*
algo:
keep map of runningLongestSubsequence that ends in each letter. loop through String s. for each char, try appending
to runningLongestSubsequence for that char, as well as to runningLongestSubsequence for preceding char.
update map with whichever results in longer subsequence.
for String s = "ieaeiouiaooeeeaaeiou", final map is:
terminal letter in longest running subsequence-> longest running subsequence
a -> aaaa
e -> aeeeee
i -> aeeeeei
o -> aeeeeeio
u -> aeeeeeiou
naming:
precCharMap - precedingCharMap
runningLongestSubMap - runningLongestSubsequenceMap
*/
public static int longestSubsequence(String s) {
if (s.length() <= 0) throw new IllegalArgumentException();
Map<Character, Character> precCharMap = new HashMap<>();
precCharMap.put('u', 'o');
precCharMap.put('o', 'i');
precCharMap.put('i', 'e');
precCharMap.put('e', 'a');
Map<Character, String> runningLongestSubMap = new HashMap<>();
for (char currChar : s.toCharArray()) {
//get longest subs
String currCharLongestSub;
String precCharLongestSub = null;
if (currChar == 'a') {
currCharLongestSub = runningLongestSubMap.getOrDefault(currChar, "");
} else {
currCharLongestSub = runningLongestSubMap.get(currChar);
char precChar = precCharMap.get(currChar);
precCharLongestSub = runningLongestSubMap.get(precChar);
}
//update running longest subsequence map
if (precCharLongestSub == null && currCharLongestSub != null) {
updateRunningLongestSubMap(currCharLongestSub, currChar, runningLongestSubMap);
} else if (currCharLongestSub == null && precCharLongestSub != null) {
updateRunningLongestSubMap(precCharLongestSub, currChar, runningLongestSubMap);
} else if (currCharLongestSub != null && precCharLongestSub != null) {
//pick longer
if (currCharLongestSub.length() < precCharLongestSub.length()) {
updateRunningLongestSubMap(precCharLongestSub, currChar, runningLongestSubMap);
} else {
updateRunningLongestSubMap(currCharLongestSub, currChar, runningLongestSubMap);
}
}
}
if (runningLongestSubMap.get('u') == null) {
return 0;
}
return runningLongestSubMap.get('u').length();
}
private static void updateRunningLongestSubMap(String longestSub, char currChar,
Map<Character, String> runningLongestSubMap) {
String currCharLongestSub = longestSub + currChar;
runningLongestSubMap.put(currChar, currCharLongestSub);
}
public static void main(String[] args) {
//String s = "aeeiooua"; //7
//String s = "aeiaaioooaauuaeiou"; //10
String s = "ieaeiouiaooeeeaaeiou"; //9
//String s = "ieaeou"; //0
//String s = "ieaeoooo"; //0
//String s = "aeiou"; //5
//if u have String s beginning in "ao", it'll do nothing with o and
//continue on to index 2.
System.out.println(longestSubsequence(s));
}
}
#include <iostream>
#include<string>
#include<cstring>
using namespace std;
unsigned int getcount(string a, unsigned int l,unsigned int r );
int main()
{
std::string a("aaaaaeeeeaaaaiiioooeeeeuuuuuuiiiiiaaaaaaoo"
"oooeeeeiiioooouuuu");
//std::string a("aaaaaeeeeaaaaiiioooeeeeuuuuuuiiiiiaaaaaaoooooeeeeiiioooo");
//std::string a("aaaaaeeeeaaaaiiioooeeeeiiiiiaaaaaaoooooeeeeiiioooo"); //sol0
//std::string a{"aeiou"};
unsigned int len = a.length();
unsigned int i=0,cnt =0,countmax =0;
bool newstring = true;
while(i<len)
{
if(a.at(i) == 'a' && newstring == true)
{
newstring = false;
cnt = getcount(a,i,len);
if(cnt > countmax)
{
countmax = cnt;
cnt = 0;
}
}
else if(a.at(i)!='a')
{
newstring = true;
}
i++;
}
cout<<countmax;
return 0;
}
unsigned int getcount(string a, unsigned int l,unsigned int r )
{
std::string b("aeiou");
unsigned int seq=0,cnt =0;
unsigned int current =l;
bool compstr = false;
while(current<r)
{
if(a.at(current) == b.at(seq))
{
cnt++;
}
else if((seq <= (b.size()-2)) && (a.at(current) == b.at(seq+1)))
{
seq++;
cnt++;
if (seq == 4)
compstr =true;
}
current++;
}
if (compstr == true)
return cnt;
return 0;
}
you can use recursive approach here (this should work for string length upto max int (easily memorization can be used)
public class LMV {
static final int NOT_POSSIBLE = -1000000000;
// if out put is this i.e soln not possible
static int longestSubsequence(String s, char[] c) {
//exit conditions
if(s.length() ==0 || c.length ==0){
return 0;
}
if(s.length() < c.length){
return NOT_POSSIBLE;
}
if(s.length() == c.length){
for(int i=0; i<s.length(); i++){
if(s.charAt(i) !=c [i]){
return NOT_POSSIBLE;
}
}
return s.length();
}
if(s.charAt(0) < c[0]){
// ignore, go ahead with next item
return longestSubsequence(s.substring(1), c);
} else if (s.charAt(0) == c[0]){
// <case 1> include item and start search for next item in chars
// <case 2> include but search for same item again in chars
// <case 3> don't include item
return Math.max(
Math.max( ( 1+longestSubsequence(s.substring(1), Arrays.copyOfRange(c, 1, c.length) ) ),
( 1+longestSubsequence(s.substring(1), c ) ) ),
( longestSubsequence(s.substring(1), c )) );
} else {
//ignore
return longestSubsequence(s.substring(1), c);
}
}
public static void main(String[] args) {
char[] chars = {'a', 'e', 'i', 'o', 'u'};
String s1 = "aeio";
String s2 = "aaeeieou";
String s3 = "aaeeeieiioiiouu";
System.out.println(longestSubsequence(s1, chars));
System.out.println(longestSubsequence(s2, chars));
System.out.println(longestSubsequence(s3, chars));
}
}
int func( char *p)
{
char *temp = p;
char ae[] = {'a','e','i','o','u'};
int size = strlen(p), i = 0;
int chari = 0, count_aeiou=0;
for (i=0;i<=size; i++){
if (temp[i] == ae[chari]) {
count_aeiou++;
}
else if ( temp[i] == ae[chari+1]) {
count_aeiou++;
chari++;
}
}
if (chari == 4 ) {
printf ("Final count : %d ", count_aeiou);
} else {
count_aeiou = 0;
}
return count_aeiou;
}
The solution to retrun the VOWELS count as per the hackerrank challenge.
int findsubwithcontinuousvowel(string str){
int curr=0;
int start=0,len=0,maxlen=0,i=0;
for(i=0;i<str.size();i++){
if(str[i]=='u' && (current[curr]=='u' || (curr+1<5 && current[curr+1]=='u'))){
//len++;
maxlen=max(len+1,maxlen);
}
if(str[i]==current[curr]){
len++;
}
else if(curr+1<5 && str[i]==current[curr+1]){
len++;
curr++;
}
else{
len=0;
curr=0;
if(str[i]=='a'){
len=1;
}
}
}
return maxlen;
}
Check if vowels are available in sequence in isInSequence and process the result on processor.
public class one {
private char[] chars = {'a','e','i','o','u'};
private int a = 0;
private boolean isInSequence(char c){
// check if char is repeating
if (c == chars[a]){
return true;
}
// if vowels are in sequence and just passed by 'a' and so on...
if (c == 'e' && a == 0){
a++;
return true;
}
if (c == 'i' && a == 1){
a++;
return true;
}
if (c == 'o' && a == 2){
a++;
return true;
}
if (c == 'u' && a == 3){
a++;
return true;
}
return false;
}
private char[] processor(char[] arr){
int length = arr.length-1;
int start = 0;
// In case if all chars are vowels, keeping length == arr
char array[] = new char[length];
for (char a : arr){
if (isInSequence(a)){
array[start] = a;
start++;
}
}
return array;
}
public static void main(String args[]){
char[] arr = {'m','a','e','l','x','o','i','o','u','a'};
one o = new one();
System.out.print(o.processor(arr));
}
}
#include <bits/stdc++.h>
#define ios ios::sync_with_stdio(NULL);cin.tie(NULL);cout.tie(NULL);
#define ll unsigned long long
using namespace std;
int main() {
// your code goes here
ios
string s;
cin>>s;
int n=s.length();
int dp[n+1][5]={0};
for(int i=1;i<=n;i++)
{
if(s[i-1]=='a')
{
dp[i][0]=1+dp[i-1][0];
dp[i][1]=dp[i-1][1];
dp[i][2]=dp[i-1][2];
dp[i][3]=dp[i-1][3];
dp[i][4]=dp[i-1][4];
}
else if(s[i-1]=='e')
{dp[i][0]=dp[i-1][0];
if(dp[i-1][0]>0)
{dp[i][1]=1+max(dp[i-1][1],dp[i-1][0]);}
else
dp[i-1][1]=0;
dp[i][2]=dp[i-1][2];
dp[i][3]=dp[i-1][3];
dp[i][4]=dp[i-1][4];
}
else if(s[i-1]=='i')
{dp[i][0]=dp[i-1][0];
if(dp[i-1][1]>0)
{dp[i][2]=1+max(dp[i-1][1],dp[i-1][2]);}
else
dp[i-1][2]=0;
dp[i][1]=dp[i-1][1];
dp[i][3]=dp[i-1][3];
dp[i][4]=dp[i-1][4];
}
else if(s[i-1]=='o')
{dp[i][0]=dp[i-1][0];
if(dp[i-1][2]>0)
{dp[i][3]=1+max(dp[i-1][3],dp[i-1][2]);}
else
dp[i-1][3]=0;
dp[i][2]=dp[i-1][2];
dp[i][1]=dp[i-1][1];
dp[i][4]=dp[i-1][4];
}
else if(s[i-1]=='u')
{dp[i][0]=dp[i-1][0];
if(dp[i-1][3]>0)
{dp[i][4]=1+max(dp[i-1][4],dp[i-1][3]);}
else
dp[i-1][4]=0;
dp[i][1]=dp[i-1][1];
dp[i][3]=dp[i-1][3];
dp[i][2]=dp[i-1][2];
}
else
{
dp[i][0]=dp[i-1][0];
dp[i][1]=dp[i-1][1];
dp[i][2]=dp[i-1][2];
dp[i][3]=dp[i-1][3];
dp[i][4]=dp[i-1][4];
}
}
cout<<dp[n][4];
return 0;
}

Linked list by reference or by value?

Here is the question. Say a linked list is implemented as follows (Java):
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
Consider the linked list:
1 -> 2 -> 3 -> 4
I do something like:
ListNode newHead = head;
newHead = head.next.next;
//Now newHead is pointing to (3) in the linked list.
Now I perform the magic:
newHead.val = 87
The linked list becomes:
1 -> 2 -> 87 -> 4
If I printed head and NOT newHead.
Why is this? I didn't modify anything with head but it still changed?
So you can use this:
Node Class:
public class IntNode {
int value;
IntNode next;
public IntNode(int value) {
this.value = value;
}
}
Singly Linked List Class:
/**
* A singly-linked list of integer values with fast addFirst and addLast methods
*/
public class LinkedIntList {
IntNode first;
IntNode last;
int size;
/**
* Return the integer value at position 'index'
*/
int get(int index) {
return getNode(index).value;
}
/**
* Set the integer value at position 'index' to 'value'
*/
void set(int index, int value) {
getNode(index).value = value;
}
/**
* Returns whether the list is empty (has no values)
*/
boolean isEmpty() {
return size == 0;
}
/**
* Inserts 'value' at position 0 in the list.
*/
void addFirst(int value) {
IntNode newNode = new IntNode(value);
newNode.next = first;
first = newNode;
if(last == null)
last = newNode;
size++;
}
/**
* Appends 'value' at the end of the list.
*/
void addLast(int value) {
IntNode newNode = new IntNode(value);
if(isEmpty())
first = newNode;
else
last.next = newNode;
last = newNode;
size++;
}
/**
* Removes and returns the first value of the list.
*/
int removeFirst() {
if(isEmpty()) {
System.out.println("RemoveFirst() on empty list!");
System.exit(-1);
}
int value = first.value;
if(first == last) {
// List has only one element, so just clear it
clear();
}
else {
first = first.next;
size--;
}
return value;
}
/**
* Removes and returns the last value of the list.
*/
int removeLast() {
if(isEmpty()) {
System.out.println("RemoveLast() on empty list!");
System.exit(-1);
}
int value = last.value;
if(first == last) {
// List has only one element, so just clear it
clear();
}
else {
// List has more than one element
IntNode currentNode = first;
while(currentNode.next != last)
currentNode = currentNode.next;
currentNode.next = null;
last = currentNode;
size--;
}
return value;
}
/**
* Removes all values from the list, making the list empty.
*/
void clear() {
first = last = null;
size = 0;
}
/**
* Returns a new int-array with the same contents as the list.
*/
int[] toArray() {
int[] array = new int[size];
int i = 0;
for(IntNode n = first; n != null; n = n.next, i++)
array[i] = n.value;
return array;
}
/**
* For internal use only.
*/
IntNode getNode(int index) {
if(index < 0 || index >= size) {
System.out.println("GetNode() with invalid index: " + index);
System.exit(-1);
}
IntNode current = first;
for(int i = 0; i < index; i++)
current = current.next;
return current;
}
}
See the comments in the code for description.

Do i just have to start again?

Put it to me plain and simple please. I was trying to implement a circular doubly linked list with a sentinel node and came up with some higher or lower game that goes backward and forwards and loops through the players. It works fine.... Except I realise i had to have two separate files for the ring module (a .h and a .c) and then a separate main file. The code is long and i have't tidied it up after i realised my mistake as it would be pointless. So im not asking you to read it or check for mistakes or anything. But if you can tell me on a scale of 1-10 how bad the situation is by just skimming over it, i would be very grateful. Just so i can get my head around the scale of what im going to have to do... thanks
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <time.h>
#define PLAYERLIMIT 5
//Doubly linked list implementation
struct Node {
char data[20];
struct Node* next;
struct Node* prev;
};
struct Node* sentinel; //global pointer to the sentinel node
struct Node* head;
struct Node* tail;
// Create sentinel node, originally it just points to itself
struct Node* MakeSentinel () {
struct Node* SentinelNode =
(struct Node*)malloc(sizeof(struct Node));
SentinelNode->next = SentinelNode->next;
SentinelNode->prev = SentinelNode->prev;
return SentinelNode;
}
//Creation of a node takes an int and returns a node
struct Node* GetNewNode (char *x) {
struct Node* newNode =
(struct Node*)malloc(sizeof(struct Node)); //created node in the dynamic memory
strcpy (newNode->data, x); //temp->data is same as (*temp).data
newNode->prev = NULL;
newNode->next = NULL;
return newNode;
}
//Returning a pointer to newly created node, inserts next to sentinel
void InsertAtHead (char *x){
struct Node* newNode = GetNewNode(x);
if (sentinel == NULL) {
sentinel = MakeSentinel();
head = newNode;
sentinel->next = head;
sentinel->prev = head;
head->next = sentinel;
head->prev = sentinel;
return;
}
head->prev = newNode;
newNode->next = head;
newNode->prev = sentinel;
sentinel->prev = newNode;
head = newNode;
}
void PrintHead() {
// printf("Sentinel prev is %s\n", sentinel->prev->data);
struct Node* temp = sentinel->prev;
printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
printf("The players in the game are\n\n");
while (temp != sentinel) {
printf ("%s ", temp->data);
temp = temp->next;
}
printf("\n");
printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
}
//Removing a name from the linked list
void DeleteEntry (struct Node* del) {
if ((del->next != sentinel) && (del->prev != sentinel)) {
del->next->prev = del->prev;
del->prev->next = del->next;
}
else if (del->next == sentinel) {
del->next->next = del->prev;
del->prev->next = del->next;
}
else if(del->prev == sentinel) {
del->next->prev = del->prev;
del->prev->prev = del->next;
}
// printf("Sentinel prev is now%s\n", sentinel->prev->data);
return;
}
int main(int argc, char *argv[]) {
//Entering all player names into the doubly linked list
printf ("Enter the names of the players. Press Enter after each new player\n");
printf ("Must have 5 Players'.'\n\n");
int i = 1;
char name[20];
while ((i <= PLAYERLIMIT)) {
printf("Player: ");
scanf ("%s", name);
InsertAtHead(name);
i++;
}
PrintHead();
//Starting the Game
//Initialising Variables for the game
int nextCard;
int currentCard;
int score;
char oppositeGuess[20];
int userChoice;
int playGame = 1;
struct Node* CurrentPlayer = head;
struct Node* PlayerBefore;
//Setting up the random cards
int range;
srand(time(NULL));
range = (13 - 1) + 1;
nextCard = rand() % range + 2;
currentCard = rand() % range + 2;
while (playGame == 1) {
//Change current card to past card before creating a new current card
currentCard = nextCard;
//generate a random int for card
nextCard = rand() % range + 2;
if (currentCard < 11) {
printf("\nThe current card is a %d.\n", currentCard);
}
else if (currentCard == 11) {
printf("\nThe current card is a jack.\n");
}
else if (currentCard == 12) {
printf("\nThe current card is a queen.\n");
}
else if (currentCard == 13) {
printf("\nThe current card is a king.\n");
}
else if (currentCard == 14) {
printf("\nThe current card is an ace.\n");
}
printf ("***%s it is your go!***\n", CurrentPlayer->data);
if (CurrentPlayer->prev != sentinel) {
PlayerBefore = CurrentPlayer->prev;
}
else {
PlayerBefore = sentinel->next;
}
// printf("\nThe CurrentPlayer is %s\n", CurrentPlayer->data);
// printf("The PlayerBefore is %s\n\n", PlayerBefore->data);
printf("Will the next card be higher(1) or lower(2)?\n");
scanf("%d", &userChoice);
printf("\n");
printf ("***%s would you like to guess the opposite?***\n", PlayerBefore->data);
scanf("%s", oppositeGuess);
if (strncmp(oppositeGuess, "Yes", 4) == 0) {
if (userChoice == 1) {
if (currentCard < nextCard) {
printf("\nSorry, %s was correct. You are out!\n", CurrentPlayer->data);
// printf ("\n IM GONNA DELETE %s\n", PlayerBefore->data);
DeleteEntry(PlayerBefore);
}
else if (currentCard > nextCard) {
printf ("Congratulations! player %s was wrong and is now out!\n", CurrentPlayer->data);
// printf ("\n IM GONNA DELETE %s\n", CurrentPlayer->data);
DeleteEntry(CurrentPlayer);
}
else if (currentCard == nextCard){
printf("\nCards were equal. Next players turn.\n");
}
}
else if (userChoice == 2) {
if (currentCard < nextCard) {
printf("Congratulations! player %s was wrong and is now out!\n", CurrentPlayer->data);
// printf ("\n IM GONNA DELETE %s\n", CurrentPlayer->data);
DeleteEntry(CurrentPlayer);
}
else if (currentCard > nextCard) {
printf ("\nSorry, %s was correct. You are out!\n", CurrentPlayer->data);
// printf ("\n IM GONNA DELETE %s\n", PlayerBefore->data);
DeleteEntry(PlayerBefore);
}
else if (currentCard == nextCard){
printf("\nCards were equal. Next players turn.\n");
}
}
}
if (strncmp(oppositeGuess, "No", 4) == 0) {
if (userChoice == 1) {
if (currentCard > nextCard) {
printf ("\nSorry you have guessed incorrectly, you are out!\n");
// printf ("\n IM GONNA DELETE %s\n", CurrentPlayer->data);
DeleteEntry(CurrentPlayer);
}
else if (currentCard < nextCard) {
printf("\nCongratualtions you were correct, next players turn.\n");
}
else if (currentCard == nextCard) {
printf("\nThe cards are the same. Next players turn.\n");
}
}
else if (userChoice == 2) {
if (currentCard > nextCard) {
printf ("\nCongratualtions you were correct, next players turn.\n");
}
else if (currentCard < nextCard) {
printf("\nSorry you have guessed incorrectly, you are out!\n");
// printf ("\n IM GONNA DELETE %s\n", CurrentPlayer->data);
DeleteEntry(CurrentPlayer);
}
else if (currentCard == nextCard) {
printf("\nThe cards are the same. Next players turn.\n");
}
}
else {
printf("\nPlease enter a valid choice.\n");
}
}
PrintHead();
if (CurrentPlayer->next != sentinel) {
CurrentPlayer = CurrentPlayer->next;
}
else {
CurrentPlayer = sentinel->prev;
}
if ((CurrentPlayer->next == sentinel) && (CurrentPlayer->prev == sentinel)) {
playGame = 0;
}
}
printf("%s you are the Winner!\n", CurrentPlayer->data);
}
On a scale of 1-10 I think this code is worth saving: you've taken a fairly tedious exercise (making a circular list) and turned it into something fun.
There's no problem with having separate files for different modules, you can include them with a #include command. For example if you put all the linked list stuff in mydllist.c
//Doubly linked list implementation
struct Node {
char data[20];
struct Node* next;
struct Node* prev;
};
struct Node* sentinel; //global pointer to the sentinel node
struct Node* head;
struct Node* tail;
// Create sentinel node, originally it just points to itself
struct Node* MakeSentinel () {
struct Node* SentinelNode = (struct Node*)malloc(sizeof(struct Node));
SentinelNode->next = SentinelNode->next;
SentinelNode->prev = SentinelNode->prev;
return SentinelNode;
}
//Creation of a node takes an int and returns a node
struct Node* GetNewNode (char *x) {
struct Node* newNode = (struct Node*)malloc(sizeof(struct Node)); //created node in the dynamic memory
strcpy (newNode->data, x); //temp->data is same as (*temp).data
newNode->prev = NULL;
newNode->next = NULL;
return newNode;
}
//Returning a pointer to newly created node, inserts next to sentinel
void InsertAtHead (char *x){
struct Node* newNode = GetNewNode(x);
if (sentinel == NULL) {
sentinel = MakeSentinel();
head = newNode;
sentinel->next = head;
sentinel->prev = head;
head->next = sentinel;
head->prev = sentinel;
return;
}
head->prev = newNode;
newNode->next = head;
newNode->prev = sentinel;
sentinel->prev = newNode;
head = newNode;
}
void PrintHead() {
// printf("Sentinel prev is %s\n", sentinel->prev->data);
struct Node* temp = sentinel->prev;
printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
printf("The players in the game are\n\n");
while (temp != sentinel) {
printf ("%s ", temp->data);
temp = temp->next;
}
printf("\n");
printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
}
//Removing a name from the linked list
void DeleteEntry (struct Node* del) {
if ((del->next != sentinel) && (del->prev != sentinel)) {
del->next->prev = del->prev;
del->prev->next = del->next;
}
else if (del->next == sentinel) {
del->next->next = del->prev;
del->prev->next = del->next;
}
else if(del->prev == sentinel) {
del->next->prev = del->prev;
del->prev->prev = del->next;
}
// printf("Sentinel prev is now%s\n", sentinel->prev->data);
return;
}
You can include it at the top of the dllist_game.c file like this:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <time.h>
#include "mydllist.c"
I'd then start by doing some simple refactorings, particularly of your main() function, to make your code easier to understand.
Along with your #define PLAYERLIMIT 5 I'd add a #define NUMBER_OF_CARDS 13 (or whatever the max number of cards is) along with an enum type for boolean values
typedef enum {true, false} bool;
That way when you define range instead of writing:
int range;
srand(time(NULL));
range = (13 - 1) + 1 //n.b. (13 - 1) + 1 = 13 is there some reason you wrote it like this?
You can write
int range = NUMBER_OF_CARDS;
srand(time(NULL));
It always a good idea to initialise variables to a default value: you might forget they're uninitialised and try to use them (which can potentially be bad):
int nextCard = 0;
int currentCard = 0;
int score = 0;
char oppositeGuess[20] = "";
int userChoice = 0 ;
bool playGame = true;
struct Node* CurrentPlayer = head;
struct Node* PreviousPlayer = head->prev;
I'd change the name of the loop counter from i to num_entered_players, so it's easier to see what the variable is for when it's in use:
int num_entered_players = 1;
char name[20];
while ((entered_players <= PLAYERLIMIT)) {
printf("Player: ");
scanf ("%s", name);
InsertAtHead(name);
num_entered_players++;
}
Finally I'd start extracting parts of the big while loop into smaller functions, which describe what's going on. For example the lines:
if (currentCard < 11) {
printf("\nThe current card is a %d.\n", currentCard);
}
else if (currentCard == 11) {
printf("\nThe current card is a jack.\n");
}
else if (currentCard == 12) {
printf("\nThe current card is a queen.\n");
}
else if (currentCard == 13) {
printf("\nThe current card is a king.\n");
}
else if (currentCard == 14) {
printf("\nThe current card is an ace.\n");
}
would become:
void printCurrentCard(int currentCard){
if (currentCard < 11) {
printf("\nThe current card is a %d.\n", currentCard);
}
else if (currentCard == 11) {
printf("\nThe current card is a jack.\n");
}
else if (currentCard == 12) {
printf("\nThe current card is a queen.\n");
}
else if (currentCard == 13) {
printf("\nThe current card is a king.\n");
}
else if (currentCard == 14) {
printf("\nThe current card is an ace.\n");
}
}
and would be called like this:
while (playGame == true) {
//Change current card to past card before creating a new current card
currentCard = nextCard;
//generate a random int for card
nextCard = rand() % range + 2;
printCurrentCard(currentCard);
....
}
etc. So if you change the rules of the game in a particular step, there's only one place you'll need to change the code - and it shouldn't affect the rest of the game.
Once you've done these changes - the logic of your game can go into another pair of .c and .h files and you can call it directly from a separate main()!

Nodes at a distance k in binary tree

You are given a function printKDistanceNodes which takes in a root node of a binary tree, a start node and an integer K. Complete the function to print the value of all the nodes (one-per-line) which are a K distance from the given start node in sorted order. Distance can be upwards or downwards.
private void printNodeAtN(Node root, Node start, int k) {
if (root != null) {
// calculate if the start is in left or right subtree - if start is
// root this variable is null
Boolean left = isLeft(root, start);
int depth = depth(root, start, 0);
if (depth == -1)
return;
printNodeDown(root, k);
if (root == start)
return;
if (left) {
if (depth > k) {
// print the nodes at depth-k level in left tree
printNode(depth - k - 1, root.left);
} else if (depth < k) {
// print the nodes at right tree level k-depth
printNode(k - depth - 1, root.right);
} else {
System.out.println(root.data);
}
} else {
// similar if the start is in right subtree
if (depth > k) {
// print the nodes at depth-k level in left tree
printNode(depth - k - 1, root.right);
} else if (depth < k) {
// print the nodes at right tree level k-depth
printNode(k - depth - 1, root.left);
} else {
System.out.println(root.data);
}
}
}
}
// print the nodes at depth - "level" from root
void printNode(int level, Node root) {
if (level == 0 && root != null) {
System.out.println(root.data);
} else {
printNode(level - 1, root.left);
printNode(level - 1, root.right);
}
}
// print the children of the start
void printNodeDown(Node start, int k) {
if (start != null) {
if (k == 0) {
System.out.println(start.data);
}
printNodeDown(start.left, k - 1);
printNodeDown(start.right, k - 1);
}
}
private int depth(Node root, Node node, int d) {
if (root == null)
return -1;
if (root != null && node == root) {
return d;
} else {
int left = depth(root.left, node, d + 1);
int right = depth(root.right, node, d + 1);
if (left > right)
return left;
else
return right;
}
}
There is at most one node at distance K which upwards - just start from the start node and move up along parents for K steps. Add this to a sorted data structure.
Then you need to add the downward nodes. To do that you can do a BFS with queue, where you store the depth together with the node when you insert it in the queue (the starting node is at level 0, it's children at level 1 and so on). Then when you pop the nodes if they are at level K add them to the sorted data structure. when you start poping nodes at level K+1 you can stop.
Finally print the nodes from the sorted data structure (they will be sorted).
EDIT: If there is no parent pointer:
Write a recursive function int Go(Node node), which returns the depth of the start node with respect to the passed in node and -1 if the subtree of node doesn't contain start. The function will find the K-th parent as a side effect. Pseudo code:
static Node KthParent = null;
static Node start = ...;
static int K = ...;
int Go(Node node) {
if (node == start) return 0;
intDepth = -1;
if(node.LeftChild != null) {
int leftDepth = Go(node.LeftChild);
if(leftDepth >= 0) intDepth = leftDepth+1;
}
if (intDepth < 0 && node.rightChild != null) {
int rightDepth = Go(node.RightChild);
if(rightDepth >= 0) intDepth = rightDepth+1;
}
if(intDepth == K) KthParent = node;
return intDepth;
}
private static int printNodeAtK(Node root, Node start, int k, boolean found){
if(root != null){
if(k == 0 && found){
System.out.println(root.data);
}
if(root==start || found == true){
int leftd = printNodeAtK(root.left, start, k-1, true);
int rightd = printNodeAtK(root.right,start,k-1,true);
return 1;
}else{
int leftd = printNodeAtK(root.left, start, k, false);
int rightd = printNodeAtK(root.right,start,k,false);
if(leftd == k || rightd == k){
System.out.println(root.data);
}
if(leftd != -1 && leftd > rightd){
return leftd+1;
}else if(rightd != -1 && rightd>leftd){
return rightd+1;
}else{
return -1;
}
}
}
return -1;
}
struct node{
int data;
node* left;
node* right;
bool printed;
};
void print_k_dist(node** root,node** p,int k,int kmax);
void reinit_printed(node **root);
void print_k_dist(node** root,node **p,int k,int kmax)
{
if(*p==NULL) return;
node* par=parent(root,p);
if(k<=kmax &&(*p)->printed==0)
{
cout<<(*p)->data<<" ";
(*p)->printed=1;
k++;
print_k_dist(root,&par,k,kmax);
print_k_dist(root,&(*p)->left,k,kmax);
print_k_dist(root,&(*p)->right,k,kmax);
}
else
return;
}
void reinit_printed(node **root)
{
if(*root==NULL) return;
else
{
(*root)->printed=0;
reinit_printed(&(*root)->left);
reinit_printed(&(*root)->right);
}
}
typedef struct node
{
int data;
struct node *left;
struct node *right;
}node;
void printkdistanceNodeDown(node *n, int k)
{
if(!n)
return ;
if(k==0)
{
printf("%d\n",n->data);
return;
}
printkdistanceNodeDown(n->left,k-1);
printkdistanceNodeDown(n->right,k-1);
}
void printkdistanceNodeDown_fromUp(node* target ,int *k)
{
if(!target)
return ;
if(*k==0)
{
printf("%d\n",target->data);
return;
}
else
{
int val=*k;
printkdistanceNodeDown(target,val-1);
}
}
int printkdistanceNodeUp(node* root, node* n , int k)
{
if(!root)
return 0;
if(root->data==n->data)
return 1;
int pl=printkdistanceNodeUp(root->left,n,k);
int pr=printkdistanceNodeUp(root->right,n,k);
if(pl )
{
k--;
if(k==0)
printf("%d\n",root->data);
else
{
printkdistanceNodeDown_fromUp(root->right,k);
printkdistanceNodeDown_fromUp(root->left,k-1);
}
return 1;
}
if(pr )
{
k--;
if(k==0)
printf("%d\n",root->data);
else
{
printkdistanceNodeDown_fromUp(root->left,k);
printkdistanceNodeDown_fromUp(root->right,k-1);
}
return 1;
}
return 0;
}
void printkdistanceNode(node* root, node* n , int k )
{
if(!root)
return ;
int val=k;
printkdistanceNodeUp(root,n,k);
printkdistanceNodeDown(n,val);
}
caller function: printkdistanceNode(root,n,k);
The output will print all the nodes at a distance k from given node upward and downward.
Here in this code PrintNodesAtKDistance will first try to find the required node.
if(root.value == requiredNode)
When we find the desired node we print all the child nodes at the distance K from this node.
Now our task is to print all nodes which are in other branches(Go up and print). We return -1 till we didn't find our desired node. As we get our desired node we get lPath or rPath >=0 . Now we have to print all nodes which are at distance (lPath/rPath) -1
public void PrintNodes(Node Root, int requiredNode, int iDistance)
{
PrintNodesAtKDistance(Root, requiredNode, iDistance);
}
public int PrintNodesAtKDistance(Node root, int requiredNode, int iDistance)
{
if ((root == null) || (iDistance < 0))
return -1;
int lPath = -1, rPath = -1;
if(root.value == requiredNode)
{
PrintChildNodes(root, iDistance);
return iDistance - 1;
}
lPath = PrintNodesAtKDistance(root.left, requiredNode, iDistance);
rPath = PrintNodesAtKDistance(root.right, requiredNode, iDistance);
if (lPath > 0)
{
PrintChildNodes(root.right, lPath - 1);
return lPath - 1;
}
else if(lPath == 0)
{
Debug.WriteLine(root.value);
}
if(rPath > 0)
{
PrintChildNodes(root.left, rPath - 1);
return rPath - 1;
}
else if (rPath == 0)
{
Debug.WriteLine(root.value);
}
return -1;
}
public void PrintChildNodes(Node aNode, int iDistance)
{
if (aNode == null)
return;
if(iDistance == 0)
{
Debug.WriteLine(aNode.value);
}
PrintChildNodes(aNode.left, iDistance - 1);
PrintChildNodes(aNode.right, iDistance - 1);
}
Here is complete java program . Inspired from geeksforgeeks Algorith
// Java program to print all nodes at a distance k from given node
class BinaryTreePrintKDistance {
Node root;
/*
* Recursive function to print all the nodes at distance k in tree (or
* subtree) rooted with given root.
*/
void printKDistanceForDescendant(Node targetNode, int currentDist,
int inputDist) {
// Base Case
if (targetNode == null || currentDist > inputDist)
return;
// If we reach a k distant node, print it
if (currentDist == inputDist) {
System.out.print(targetNode.data);
System.out.println("");
return;
}
++currentDist;
// Recur for left and right subtrees
printKDistanceForDescendant(targetNode.left, currentDist, inputDist);
printKDistanceForDescendant(targetNode.right, currentDist, inputDist);
}
public int printkdistance(Node targetNode, Node currentNode,
int inputDist) {
if (currentNode == null) {
return -1;
}
if (targetNode.data == currentNode.data) {
printKDistanceForDescendant(currentNode, 0, inputDist);
return 0;
}
int ld = printkdistance(targetNode, currentNode.left, inputDist);
if (ld != -1) {
if (ld + 1 == inputDist) {
System.out.println(currentNode.data);
} else {
printKDistanceForDescendant(currentNode.right, 0, inputDist
- ld - 2);
}
return ld + 1;
}
int rd = printkdistance(targetNode, currentNode.right, inputDist);
if (rd != -1) {
if (rd + 1 == inputDist) {
System.out.println(currentNode.data);
} else {
printKDistanceForDescendant(currentNode.left, 0, inputDist - rd
- 2);
}
return rd + 1;
}
return -1;
}
// Driver program to test the above functions
#SuppressWarnings("unchecked")
public static void main(String args[]) {
BinaryTreePrintKDistance tree = new BinaryTreePrintKDistance();
/* Let us construct the tree shown in above diagram */
tree.root = new Node(20);
tree.root.left = new Node(8);
tree.root.right = new Node(22);
tree.root.left.left = new Node(4);
tree.root.left.right = new Node(12);
tree.root.left.right.left = new Node(10);
tree.root.left.right.right = new Node(14);
Node target = tree.root.left;
tree.printkdistance(target, tree.root, 2);
}
static class Node<T> {
public Node left;
public Node right;
public T data;
Node(T data) {
this.data = data;
}
}
}

Add two big numbers represented as linked lists without reversing the linked lists

Suppose you have 2 big numbers represented as linked lists, how do you add them and store the result in a separate linked list.
eg
a = 2 -> 1 -> 7
b = 3 -> 4
result = 2 -> 5 -> 1
Can you add them without reversing the linked lists
Pseudocode:
Step 1. Traverse the linked lists and push the elements in two different stacks
Step 2. Pop the top elements from both the stacks
Step 3. Add the elements (+ any carry from previous additions) and store the carry in a temp variable
Step 4. Create a node with the sum and insert it into beginning of the result list
I think this's something beyond context but can be very performance incentive for the person who originally posted this question.
So here's a recommendation:
instead of using every node as a single digit of the number, use each node to store a large number(close to the size of integer) and if the highest possible number you chose to store in each node be x(your case 9) then you can view your number as a representation in base x+1.
where each digit is a number between 0 and x.
This would give you significant performance gain as the algorithm would run in O(log n) time and require the same number of nodes as against O(n) in your case , n being the number of decimal digits of the larger of two addends.
Typically for the ease of your algorithm, you can choose a power of 10 as the base which fits in the range of your integer.
For example if your number be 1234567890987654321 and you want to store it in linked list choosing the base to be 10^8 then your representation should look like:
87654321-> 4567890 -> 123(little endian)
Here's my hacky attempt in Java that runs in about O(max(len(a),len(b))). I've provided a complete sample with a very simple singly linked list implementation. It's quite late here so the code is not as nice as I'd like - sorry!
This code assumes:
That the length of the lists is known
Singly linked list
Dealing with integer data
It uses recursion to propagate the sums and carry for each digit, and sums left to right. The lists are never reversed - sums are performed left to right, and carry propagates up the recursive stack. It could be unrolled in an iterative solution, but I won't worry about that.
public class LinkedListSum {
static class LLNode {
int value;
LLNode next;
public LLNode(int value){
this.value = value;
}
public int length(){
LLNode node = this;
int count = 0;
do {
count++;
} while((node = node.next) != null);
return count;
}
public List<Integer> toList(){
List<Integer> res = new ArrayList<Integer>();
LLNode node = this;
while(node != null){
res.add(node.value);
node = node.next;
}
return res;
}
}
public static void main(String[] argc){
LLNode list_a = fromArray(new int[]{4,7,4,7});
LLNode list_b = fromArray(new int[]{5,3,7,4,7,4});
System.out.println("Sum: " + sum(list_a, list_b).toList());
}
private static LLNode fromArray(int[] arr){
LLNode res = new LLNode(0);
LLNode current = res;
for(int i = 0; i < arr.length; i++){
LLNode node = new LLNode(arr[i]);
current.next = node;
current = node;
}
return res.next;
}
private static LLNode sum(LLNode list_1, LLNode list_2){
LLNode longer;
LLNode shorter;
if(list_1.length() >= list_2.length()){
longer = list_1;
shorter = list_2;
} else {
longer = list_2;
shorter = list_1;
}
// Pad short to same length as long
int diff = longer.length() - shorter.length();
for(int i = 0; i < diff; i++){
LLNode temp = new LLNode(0);
temp.next = shorter;
shorter = temp;
}
System.out.println("Longer: " + longer.toList());
System.out.println("Shorter: " + shorter.toList());
return sum_same_length(new LLNode(0), null, longer, shorter);
}
private static LLNode sum_same_length(LLNode current, LLNode previous, LLNode longerList, LLNode shorterList){
LLNode result = current;
if(longerList == null){
previous.next = null;
return result;
}
int sum = longerList.value + shorterList.value;
int first_value = sum % 10;
int first_carry = sum / 10;
current.value = first_value;
// Propagate the carry backwards - increase next multiple of 10 if necessary
LLNode root = propagateCarry(current,previous,first_carry);
current.next = new LLNode(0);
sum_same_length(current.next, current, longerList.next, shorterList.next);
// Propagate the carry backwards - increase next multiple of 10 if necessary:
// The current value could have been increased during the recursive call
int second_value = current.value % 10;
int second_carry = current.value / 10;
current.value = second_value;
root = propagateCarry(current,previous,second_carry);
if(root != null) result = root;
return result;
}
// Returns the new root of the linked list if one had to be added (due to carry)
private static LLNode propagateCarry(LLNode current, LLNode previous, int carry){
LLNode result = null;
if(carry != 0){
if(previous != null){
previous.value += carry;
} else {
LLNode first = new LLNode(carry);
first.next = current;
result = first;
}
}
return result;
}
}
Here is a pseudo code.
list *add (list *l1, list *l2)
{
node *l3, l3_old;
while (l1 != NULL)
{
stack1.push (l1);
l1 = l1->next;
}
while (l2 != NULL)
{
stack2.push (l2);
l2 = l2->next;
}
l3_old = NULL;
while (!stack1.isempty () && !stack2.isempty ()) // at least one stack is not empty
{
l3 = get_new_node ();
l1 = stack1.pop ();
l2 = stack2.pop ();
l3->val = l1->val + l2->val;
if (l3_old != NULL)
{
l3->val = l3->val + (int)l3_old/10;
l3_old->val %= 10;
}
l3->next = l3_old;
l3_old = l3;
}
while (!stack1.isempty ())
{
l1 = stack1.pop ();
l3 = get_new_node ();
l3->val = l1->val + (int)l3_old->val/10;
l3_old->val %= 10;
l3->next = l3_old;
l3_old = l3;
}
while (!stack2.isempty ())
{
l2 = stack2.pop ();
l3 = get_new_node ();
l3->val = l2->val + (int)l3_old->val/10;
l3_old->val %= 10;
l3->next = l3_old;
l3_old = l3;
}
return l3;
}
Here is my attempt, using the two linked lists and returning the sum as a new list using recursion.
public class SumList {
int[] a1= {7,3,2,8};
int[] a2= {4,6,8,4};
LinkedList l1= new LinkedList(a1);
LinkedList l2= new LinkedList(a2);
Node num1= l1.createList();
Node num2= l2.createList();
Node result;
public static void main(String[] args) {
SumList sl= new SumList();
int c= sl.sum(sl.num1, sl.num2);
if(c>0) {
Node temp= new Node(c);
temp.next= sl.result;
sl.result= temp;
}
while(sl.result != null){
System.out.print(sl.result.data);
sl.result= sl.result.next;
}
}
int sum(Node n1, Node n2) {
if(n1==null || n2==null)
return 0;
int a1= this.getSize(n1);
int a2= this.getSize(n2);
int carry, s= 0;
if(a1>a2) {
carry= sum(n1.next, n2);
s= n1.data+carry;
}
else if(a2>a1) {
carry= sum(n1, n2.next);
s= n2.data+carry;
}
else {
carry= sum(n1.next, n2.next);
s= n1.data+n2.data+carry;
}
carry= s/10;
s=s%10;
Node temp= new Node(s);
temp.next= result;
result= temp;
return carry;
}
int getSize(Node n) {
int count =0;
while(n!=null) {
n=n.next;
count++;
}
return count;
}
}
// A recursive program to add two linked lists
#include <stdio.h>
#include <stdlib.h>
// A linked List Node
struct node
{
int data;
struct node* next;
};
typedef struct node node;
/* A utility function to insert a node at the beginning of linked list */
void push(struct node** head_ref, int new_data)
{
/* allocate node */
struct node* new_node = (struct node*) malloc(sizeof(struct node));
/* put in the data */
new_node->data = new_data;
/* link the old list off the new node */
new_node->next = (*head_ref);
/* move the head to point to the new node */
(*head_ref) = new_node;
}
/* A utility function to print linked list */
void printList(struct node *node)
{
while (node != NULL)
{
printf("%d ", node->data);
node = node->next;
}
printf("\n");
}
// A utility function to swap two pointers
void swapPointer( node** a, node** b )
{
node* t = *a;
*a = *b;
*b = t;
}
/* A utility function to get size of linked list */
int getSize(struct node *node)
{
int size = 0;
while (node != NULL)
{
node = node->next;
size++;
}
return size;
}
// Adds two linked lists of same size represented by head1 and head2 and returns
// head of the resultant linked list. Carry is propagated while returning from
// the recursion
node* addSameSize(node* head1, node* head2, int* carry)
{
// Since the function assumes linked lists are of same size,
// check any of the two head pointers
if (head1 == NULL)
return NULL;
int sum;
// Allocate memory for sum node of current two nodes
node* result = (node *)malloc(sizeof(node));
// Recursively add remaining nodes and get the carry
result->next = addSameSize(head1->next, head2->next, carry);
// add digits of current nodes and propagated carry
sum = head1->data + head2->data + *carry;
*carry = sum / 10;
sum = sum % 10;
// Assigne the sum to current node of resultant list
result->data = sum;
return result;
}
// This function is called after the smaller list is added to the bigger
// lists's sublist of same size. Once the right sublist is added, the carry
// must be added toe left side of larger list to get the final result.
void addCarryToRemaining(node* head1, node* cur, int* carry, node** result)
{
int sum;
// If diff. number of nodes are not traversed, add carry
if (head1 != cur)
{
addCarryToRemaining(head1->next, cur, carry, result);
sum = head1->data + *carry;
*carry = sum/10;
sum %= 10;
// add this node to the front of the result
push(result, sum);
}
}
// The main function that adds two linked lists represented by head1 and head2.
// The sum of two lists is stored in a list referred by result
void addList(node* head1, node* head2, node** result)
{
node *cur;
// first list is empty
if (head1 == NULL)
{
*result = head2;
return;
}
// second list is empty
else if (head2 == NULL)
{
*result = head1;
return;
}
int size1 = getSize(head1);
int size2 = getSize(head2) ;
int carry = 0;
// Add same size lists
if (size1 == size2)
*result = addSameSize(head1, head2, &carry);
else
{
int diff = abs(size1 - size2);
// First list should always be larger than second list.
// If not, swap pointers
if (size1 < size2)
swapPointer(&head1, &head2);
// move diff. number of nodes in first list
for (cur = head1; diff--; cur = cur->next);
// get addition of same size lists
*result = addSameSize(cur, head2, &carry);
// get addition of remaining first list and carry
addCarryToRemaining(head1, cur, &carry, result);
}
// if some carry is still there, add a new node to the fron of
// the result list. e.g. 999 and 87
if (carry)
push(result, carry);
}
// Driver program to test above functions
int main()
{
node *head1 = NULL, *head2 = NULL, *result = NULL;
int arr1[] = {9, 9, 9};
int arr2[] = {1, 8};
int size1 = sizeof(arr1) / sizeof(arr1[0]);
int size2 = sizeof(arr2) / sizeof(arr2[0]);
// Create first list as 9->9->9
int i;
for (i = size1-1; i >= 0; --i)
push(&head1, arr1[i]);
// Create second list as 1->8
for (i = size2-1; i >= 0; --i)
push(&head2, arr2[i]);
addList(head1, head2, &result);
printList(result);
return 0;
}
1.First traverse the two lists and find the lengths of the two lists(Let m,n be the lengths).
2.Traverse n-m nodes in the longer list and set 'prt1' to the current node and 'ptr2' to beginning of the other list.
3.Now call the following recursive function with flag set to zero:
void add(node* ptr1,node* ptr2){
if(ptr1==NULL)
return;
add(ptr1->next,ptr2->next);
insertAtBegin(ptr1->data+ptr2->data+flag);
flag=(ptr1->data+ptr2->data)%10;
}
4.Now you need to add the remaining n-m nodes at the beginning of your target list, you can do it directly using a loop. Please note that for the last element in the loop you need to add the flag returned by the add() function as there might be a carry.
If your question is without using recursion:
1.Repeat the first two steps, then create your target list initalising every elements with '0'(make sure that the length of the list is accurate).
2.Traverse the two lists along with your target list(a step behind).If you find sum of two nodes greater than 10, make the value in the target list as '1'.
3.With the above step you took care of the carry. Now in one more pass just add the two nodes modulo 10 and add this value in the corresponding node of the target list.
without using stack .....
simply store the content of link list in array and perform addition and and then again put addition into link list
code :
#include<stdio.h>
#include<malloc.h>
typedef struct node
{
int value;
struct node *next;
}node;
int main()
{
printf("\nEnter the number 1 : ");
int ch;
node *p=NULL;
node *k=NULL;
printf("\nEnter the number of digit : ");
scanf("%d",&ch);
int i=0;
while(ch!=i)
{
i++;
node *q=NULL;
int a=0;
q=(node *)malloc(sizeof(node));
printf("\nEnter value : ");
scanf("%d",&a);
q->value=a;
if(p==NULL)
{
q->next=NULL;
p=q;
k=p;
}
else
{
q->next=NULL;
p->next=q;
p=q;
}
}
printf("\nEnter the number 2 : ");
int ch1;
node *p1=NULL;
node *k1=NULL;
int i1=0;
printf("\nEnter the number of digit : ");
scanf("%d",&ch1);
while(ch1!=i1)
{
i1++;
node *q1=NULL;
int a1=0;
q1=(node *)malloc(sizeof(node));
printf("\nEnter value : ");
scanf("%d",&a1);
q1->value=a1;
if(p1==NULL)
{
q1->next=NULL;
p1=q1;
k1=p1;
}
else
{
q1->next=NULL;
p1->next=q1;
p1=q1;
}
}
printf("\n\t");
int arr1[100];
int arr1_ptr=0;
while(k != NULL )
{
printf("%d\t",k->value);
arr1[arr1_ptr++]=k->value;
k=k->next;
}
printf("\n\t");
int arr2[100];
int arr2_ptr=0;
while(k1 != NULL )
{
printf("%d\t",k1->value);
arr2[arr2_ptr++]=k1->value;
k1=k1->next;
}
//addition logic ...
int result[100]={0};
int result_ptr=0;
int loop_ptr=0;
int carry=0;
arr1_ptr--;
arr2_ptr--;
if(arr1_ptr>arr2_ptr)
loop_ptr=arr1_ptr+1;
else
loop_ptr=arr2_ptr+1;
for(int i = loop_ptr ; i >= 0;i--)
{
if(arr1_ptr >= 0 && arr2_ptr >= 0)
{
if( (arr1[arr1_ptr] + arr2[arr2_ptr] + carry ) > 9 )
{
result[i]=((arr1[arr1_ptr] + arr2[arr2_ptr]+carry) % 10 );
carry = ((arr1[arr1_ptr--] + arr2[arr2_ptr--]+carry ) / 10 ) ;
}
else
{
result[i]=(arr1[arr1_ptr--] + arr2[arr2_ptr--] + carry );
carry = 0 ;
}
}
else if( !(arr1_ptr < 0 ) || !( arr2_ptr < 0 ) )
{
if( arr1_ptr < 0)
result[i]=arr2[arr2_ptr--]+carry;
else
result[i]=arr1[arr1_ptr--]+carry;
}
else
result[i]=carry;
}
/*printf("\n");
for(int i=0;i<loop_ptr+1;i++)
printf("%d\t",result[i]);
*/
node *k2=NULL,*p2=NULL;
for(int i=0;i<loop_ptr+1;i++)
{
node *q2=NULL;
q2=(node *)malloc(sizeof(node));
q2->value=result[i];
if(p2==NULL)
{
q2->next=NULL;
p2=q2;
k2=p2;
}
else
{
q2->next=NULL;
p2->next=q2;
p2=q2;
}
}
printf("\n");
while(k2 != NULL )
{
printf("%d\t",k2->value);
k2=k2->next;
}
return 0;
}
We can add them by using recursion. Assume the question is defined as follows: we have lists l1 and l2 and we want to add them by storing the result in l1. For simplicity assume that both lists have the same length (the code can be easily modified to work for different lengths). Here is my working Java solution:
private static ListNode add(ListNode l1, ListNode l2){
if(l1 == null)
return l2;
if(l2 == null)
return l1;
int[] carry = new int[1];
add(l1, l2, carry);
if(carry[0] != 0){
ListNode newHead = new ListNode(carry[0]);
newHead.next = l1;
return newHead;
}
return l1;
}
private static void add(ListNode l1, ListNode l2, int[] carry) {
if(l1.next == null && l2.next == null){
carry[0] = l1.val + l2.val;
l1.val = carry[0]%10;
carry[0] /= 10;
return;
}
add(l1.next, l2.next, carry);
carry[0] += l1.val + l2.val;
l1.val = carry[0]%10;
carry[0] /= 10;
}
Input : List a , List b
Output : List c
Most approaches here require extra space for List a and List b. This can be removed.
Reverse List a and List b so that they are represented in the reverse order (i.e., tail as head and all the links reversed) with constant space of O(1).
Then add the lists efficiently by traversing through both of them simultaneously and maintaining a carry.
Reverse List a and List b if required
Try this
/* No Recursion, No Reversal - Java */
import java.util.*;
class LinkedListAddMSB
{
static LinkedList<Integer> addList(LinkedList<Integer> num1, LinkedList<Integer> num2)
{
LinkedList<Integer> res = new LinkedList<Integer>();
LinkedList<Integer> shorter = new LinkedList<Integer>();
LinkedList<Integer> longer = new LinkedList<Integer>();
int carry = 0;
int maxlen,minlen;
if(num1.size() >= num2.size())
{
maxlen = num1.size();
minlen = num2.size();
shorter = num2;
longer = num1;
}
else
{
maxlen = num2.size();
minlen = num1.size();
shorter = num1;
longer = num2;
}
//Pad shorter list to same length by adding preceeding 0
int diff = maxlen - minlen;
for(int i=0; i<diff; i++)
{
shorter.addFirst(0);
}
for(int i=maxlen-1; i>=0; i--)
{
int temp1 = longer.get(i);
int temp2 = shorter.get(i);
int temp3 = temp1 + temp2 + carry;
carry = 0;
if(temp3 >= 10)
{
carry = (temp3/10)%10;
temp3 = temp3%10;
}
res.addFirst(temp3);
}
if(carry > 0)
res.addFirst(carry);
return res;
}
public static void main(String args[])
{
LinkedList<Integer> num1 = new LinkedList<Integer>();
LinkedList<Integer> num2 = new LinkedList<Integer>();
LinkedList<Integer> res = new LinkedList<Integer>();
//64957
num1.add(6);
num1.add(4);
num1.add(9);
num1.add(5);
num1.add(7);
System.out.println("First Number: " + num1);
//48
num2.add(4);
num2.add(8);
System.out.println("First Number: " + num2);
res = addList(num1,num2);
System.out.println("Result: " + res);
}
}
/* this baby does not reverse the list
** , it does use recursion, and it uses a scratch array */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct list {
struct list *next;
unsigned value;
};
unsigned recurse( char target[], struct list *lp);
struct list * grab ( char buff[], size_t len);
unsigned recurse( char target[], struct list *lp)
{
unsigned pos;
if (!lp) return 0;
pos = recurse (target, lp->next);
/* We should do a bounds check target[] here */
target[pos] += lp->value;
if (target[pos] >= 10) {
target[pos+1] += target[pos] / 10;
target[pos] %= 10;
}
return 1+pos;
}
struct list * grab ( char *buff, size_t len)
{
size_t idx;
struct list *ret, **hnd;
/* Skip prefix of all zeros. */
for (idx=len; idx--; ) {
if (buff [idx] ) break;
}
if (idx >= len) return NULL;
/* Build the result chain. Buffer has it's LSB at index=0,
** but we just found the MSB at index=idx.
*/
ret = NULL; hnd = &ret;
do {
*hnd = malloc (sizeof **hnd);
(*hnd)->value = buff[idx];
(*hnd)->next = NULL;
hnd = &(*hnd)->next;
} while (idx--);
return ret;
}
int main (void)
{
char array[10];
struct list a[] = { {NULL, 2} , {NULL, 1} , {NULL, 7} };
struct list b[] = { {NULL, 3} , {NULL, 4} };
struct list *result;
a[0].next = &a[1]; a[1].next = &a[2];
b[0].next = &b[1];
memset(array, 0 , sizeof array );
(void) recurse ( array, a);
(void) recurse ( array, b);
result = grab ( array, sizeof array );
for ( ; result; result = result->next ) {
printf( "-> %u" , result->value );
}
printf( "\n" );
return 0;
}
Final version (no list reversal, no recursion):
#include <stdio.h>
#include <stdlib.h>
struct list {
struct list *nxt;
unsigned val;
};
struct list *sumlist(struct list *l, struct list *r);
int difflen(struct list *l, struct list *r);
struct list *sumlist(struct list *l, struct list *r)
{
int carry,diff;
struct list *result= NULL, **pp = &result;
/* If the lists have different lengths,
** the sum will start with the prefix of the longest list
*/
for (diff = difflen(l, r); diff; diff += (diff > 0) ? -1 : 1) {
*pp = malloc (sizeof **pp) ;
(*pp)->nxt = NULL;
if (diff > 0) { (*pp)->val = l->val; l= l->nxt; }
else { (*pp)->val = r->val; r= r->nxt; }
pp = &(*pp)->nxt ;
}
/* Do the summing.
** whenever the sum is ten or larger we increment a carry counter
*/
for (carry=0; l && r; l=l->nxt, r=r->nxt) {
*pp = malloc (sizeof **pp) ;
(*pp)->nxt = NULL;
(*pp)->val = l->val + r->val;
if ((*pp)->val > 9) carry++;
pp = &(*pp)->nxt ;
}
/* While there are any carries, we will need to propagate them.
** Because we cannot reverse the list (or walk it backward),
** this has to be done iteratively.
** Special case: if the first digit needs a carry,
** we have to insert a node in front of it
*/
for (diff =0 ;carry; carry = diff) {
struct list *tmp;
if (result && result->val > 9) {
tmp = malloc(sizeof *tmp);
tmp->nxt = result;
tmp->val = 0;
result = tmp;
}
diff=0;
for (tmp=result; tmp ; tmp= tmp->nxt) {
if (tmp->nxt && tmp->nxt->val > 9) {
tmp->val += tmp->nxt->val/10;
tmp->nxt->val %= 10; }
if (tmp->val > 9) diff++;
}
}
return result;
}
int difflen(struct list *l, struct list *r)
{
int diff;
for (diff=0; l || r; l = (l)?l->nxt:l, r = (r)?r->nxt:r ) {
if (l && r) continue;
if (l) diff++; else diff--;
}
return diff;
}
int main (void)
{
struct list one[] = { {one+1, 2} , {one+2, 6} , {NULL, 7} };
struct list two[] = { {two+1, 7} , {two+2, 3} , {NULL, 4} };
struct list *result;
result = sumlist(one, two);
for ( ; result; result = result->nxt ) {
printf( "-> %u" , result->val );
}
printf( ";\n" );
return 0;
}
In java i will do it this way
public class LLSum {
public static void main(String[] args) {
LinkedList<Integer> ll1 = new LinkedList<Integer>();
LinkedList<Integer> ll2 = new LinkedList<Integer>();
ll1.add(7);
ll1.add(5);
ll1.add(9);
ll1.add(4);
ll1.add(6);
ll2.add(8);
ll2.add(4);
System.out.println(addLists(ll1,ll2));
}
public static LinkedList<Integer> addLists(LinkedList<Integer> ll1, LinkedList<Integer> ll2){
LinkedList<Integer> finalList = null;
int num1 = makeNum(ll1);
int num2 = makeNum(ll2);
finalList = makeList(num1+num2);
return finalList;
}
private static LinkedList<Integer> makeList(int num) {
LinkedList<Integer> newList = new LinkedList<Integer>();
int temp=1;
while(num!=0){
temp = num%10;
newList.add(temp);
num = num/10;
}
return newList;
}
private static int makeNum(LinkedList<Integer> ll) {
int finalNum = 0;
for(int i=0;i<ll.size();i++){
finalNum += ll.get(i) * Math.pow(10,i);
}
return finalNum;
}
}
Here is my first try:
public class addTwo {
public static void main(String args[]){
LinkedListNode m =new LinkedListNode(3);
LinkedListNode n = new LinkedListNode(5);
m.appendNew(1);
m.appendNew(5);
m.appendNew(5);
n.appendNew(9);
n.appendNew(2);
n.appendNew(5);
n.appendNew(9);
n.appendNew(9 );
m.print();
n.print();
LinkedListNode add=addTwo(m,n);
add.print();
}
static LinkedListNode addTwo(LinkedListNode m,LinkedListNode n){
LinkedListNode result;
boolean flag =false;
int num;
num=m.data+n.data+(flag?1:0);
flag=false;
if(num>9){
flag=true;
}
result = new LinkedListNode(num%10);
while(m.link!=null && n.link!=null){
m=m.link;
n=n.link;
num=m.data+n.data+(flag?1:0);
flag=false;
if(num>9){
flag=true;
}
result.appendNew(num%10);
}
if(m.link==null && n.link==null){
if(flag)
result.appendNew(1);
flag=false;
}else if(m.link!=null){
while(m.link !=null){
m=m.link;
num=m.data;
num=m.data+(flag?1:0);
flag=false;
if(num>9){
flag=true;
}
result.appendNew(num%10);
}
}else{
while(n.link !=null){
n=n.link;
num=n.data;
num=n.data+(flag?1:0);
flag=false;
if(num>9){
flag=true;
}
result.appendNew(num%10);
}
}
if(flag){
result.appendNew(1);
}
return result;
}
class LinkedListNode {
public int data;
public LinkedListNode link;
public LinkedListNode(){System.out.println(this+":"+this.link+":"+this.data);}
public LinkedListNode(int data){
this.data=data;
}
void appendNew(int data){
if(this==null){
System.out.println("this is null");
LinkedListNode newNode = new LinkedListNode(data);
}
LinkedListNode newNode = new LinkedListNode(data);
LinkedListNode prev =this;
while(prev.link!=null){
prev = prev.link;
}
prev.link=newNode;
}
void print(){
LinkedListNode n=this;
while(n.link!=null){
System.out.print(n.data +"->");
n = n.link;
}
System.out.println(n.data);
}
}
result is:
3->1->5->5
5->9->2->5->9->9
8->0->8->0->0->0->1
My recursive Java implementation:
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
return addTwoNumbers(l1, l2, 0);
}
public ListNode addTwoNumbers(ListNode l1, ListNode l2, int carryOver) {
int result;
ListNode next = null;
if (l1 == null && l2 == null) {
if (carryOver > 0) {
return new ListNode(carryOver);
} else {
return null;
}
} else if (l1 == null && l2 != null) {
result = l2.val + carryOver;
next = addTwoNumbers(null, l2.next, result / 10);
} else if (l1 != null && l2 == null){
result = l1.val + carryOver;
next = addTwoNumbers(l1.next, null, result / 10);
} else {
result = l1.val + l2.val + carryOver;
next = addTwoNumbers(l1.next, l2.next, result / 10);
}
ListNode node = new ListNode(result % 10);
node.next = next;
return node;
}
}
Hope that helps.
/* spoiler: just plain recursion will do */
#include <stdio.h>
struct list {
struct list *next;
unsigned value;
};
struct list a[] = { {NULL, 2} , {NULL, 1} , {NULL, 7} };
struct list b[] = { {NULL, 3} , {NULL, 4} };
unsigned recurse( unsigned * target, struct list *lp);
unsigned recurse( unsigned * target, struct list *lp)
{
unsigned fact;
if (!lp) return 1;
fact = recurse (target, lp->next);
*target += fact * lp->value;
return 10*fact;
}
int main (void)
{
unsigned result=0;
/* set up the links */
a[0].next = &a[1];
a[1].next = &a[2];
b[0].next = &b[1];
(void) recurse ( &result, a);
(void) recurse ( &result, b);
printf( "Result = %u\n" , result );
return 0;
}

Resources