添加两个表示为链接列表的大数字,而不反转链接列表

时间:2011-09-03 15:35:49

标签: algorithm

假设您有2个大数字表示为链接列表,如何添加它们并将结果存储在单独的链接列表中。 例如

a = 2 -> 1 -> 7 
b = 3 -> 4
result = 2 -> 5 -> 1

您可以在不反转链接列表的情况下添加它们吗

17 个答案:

答案 0 :(得分:14)

伪代码:
步骤1.遍历链表并将元素推入两个不同的堆栈中 步骤2.从堆栈中弹出顶部元素
步骤3.添加元素(+以前添加的任何进位)并将进位存储在临时变量
中 步骤4.使用sum创建一个节点并将其插入结果列表的开头

答案 1 :(得分:5)

我认为这是超出背景的东西,但对于最初发布此问题的人来说可能是非常好的表现。

所以这是一个建议:

不是将每个节点用作数字的单个数字,而是使用每个节点存储一个大数字(接近整数的大小),如果您选择在每个节点中存储的最高数量为{{1} (您的情况9)然后您可以在x中查看您的号码作为表示。 其中每个数字都是0到x之间的数字。

这将为您带来显着的性能提升,因为算法将在O(log n)时间运行,并且在您的情况下需要与O(n)相同的节点数,n是较大的小数位数两个加数。

通常,为了方便算法,您可以选择10的幂作为适合整数范围的基数。

例如,如果您的号码是1234567890987654321并且您想将其存储在链接列表中,选择基数为10 ^ 8,那么您的表示应如下所示:

87654321-> 4567890 - > 123(小端)

答案 2 :(得分:4)

这是我在Java中的hacky尝试,运行在大约O(max(len(a),len(b)))。我提供了一个完整的示例,其中包含一个非常简单的单链表实现。现在已经很晚了,所以代码不如我想的那么好 - 抱歉!

此代码假定:

  • 已知列表的长度
  • 单链表
  • 处理整数数据

它使用递归来传播总和并携带每个数字,并从左到右求和。列表永远不会反转 - 从左到右执行求和,并且进位在递归堆栈中向上传播。它可以在迭代解决方案中展开,但我不会担心。

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;
    }
}

答案 3 :(得分:0)

1.首先遍历两个列表并找到两个列表的长度(设m,n为长度)。

2.遍历较长列表中的n-m个节点,并将'prt1'设置为当前节点,将'ptr2'设置为另一个列表的开头。

3.现在调用以下递归函数并将标志设置为零:

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.现在您需要在目标列表的开头添加剩余的n-m个节点,您可以使用循环直接完成。请注意,对于循环中的最后一个元素,您需要添加add()函数返回的标志,因为可能有一个进位。

如果您的问题不使用递归:

1.重复前两步,然后创建目标列表,使每个元素都为'0'(确保列表的长度准确)。

2.遍历两个列表以及目标列表(后退一步)。如果找到两个节点之和大于10,则将目标列表中的值设为“1”。

3.通过上述步骤,您可以处理好随身携带物品。现在在另一个传递中,只需添加模数为10的两个节点,并将此值添加到目标列表的相应节点中。

答案 4 :(得分:0)

尝试一下

/* 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);
  }
}

答案 5 :(得分:0)

Input : List a , List b
Output : List c

此处的大多数方法都需要额外的空间用于列表a和列表b。这可以删除。

  1. 反向列出a和列表b,使它们以相反的顺序表示(即尾部为头部,所有链接都反转),且空间为O(1)。
  2. 然后通过遍历两个列表并保持进位来有效地添加列表。
  3. 如果需要,反向列出a和列表b

答案 6 :(得分:0)

我们可以使用递归来添加它们。假设问题定义如下:我们列出了l1l2,我们希望通过将结果存储在l1中来添加它们。为简单起见,假设两个列表具有相同的长度(代码可以很容易地修改为适用于不同的长度)。这是我的Java解决方案:

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;
    }

答案 7 :(得分:0)

不使用堆栈..... 只需将链接列表的内容存储在数组中并执行添加,然后再将其添加到链接列表中

代码:

#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;
}  

答案 8 :(得分:0)

// 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;
}

答案 9 :(得分:0)

这是我的尝试,使用两个链表并使用递归将总和作为新列表返回。

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;
}
}

答案 10 :(得分:0)

这是伪代码。

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;
}

答案 11 :(得分:-1)

最终版本(没有列表反转,没有递归):

#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;
}

答案 12 :(得分:-1)

在java中我会这样做

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;
  }
}

答案 13 :(得分:-1)

/* 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;
}

答案 14 :(得分:-1)

这是我的第一次尝试:

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);
}
}

结果是:

3→1→5→5

5→9-&GT; 2→5→9-&GT; 9

8-&GT; 0→8-→0→0→0→1

答案 15 :(得分:-1)

我的递归Java实现:

/**
* 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;
    }
}

希望有所帮助。

答案 16 :(得分:-3)

/ *剧透:只是普通的递归会做* /

#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;
}