将链表表示的两个数字相加|设置 3
给定由两个链表表示的两个数字,编写一个返回和列表的函数。和表是两个输入数相加的链表表示。预期空间复杂度 O(1)。
例子:
Input:
L1 = 5 -> 6 -> 3 -> NULL
L2 = 8 -> 4 -> 2 -> NULL
Output: 1 -> 4 -> 0 -> 5 -> NULL
Input:
L1 = 1 -> 0 -> 0 -> NULL
L2 = 9 -> 1 -> NULL
Output: 1 -> 9 -> 1 -> NULL
方法:我们在这里讨论了一个解决方案,我们使用递归到达列表中的最低有效数,但由于堆栈的参与,该解决方案的空间复杂度变为 O(N)
这里的目标是就地求和,并返回修改后的求和列表。
这个想法是首先反转两个链表,因此列表的新头指向最低有效数,我们可以按照此处所述开始添加,而不是创建新列表,我们修改现有列表并返回修改后的列表的头部.
以下是步骤:
- 反向列表 L1。
- 反向列表 L2。
- 迭代添加两个列表的节点。
- 反转结果列表并返回其头部。
下面是上述方法的实现:
C++
// C++ implementation of the approach
#include
using namespace std;
class LinkedList;
// Node class for the linked list
class Node {
int data;
Node* next;
friend LinkedList;
public:
Node();
Node(int x);
};
Node::Node()
{
data = 0;
next = NULL;
}
// Function to initialise
// a node with value x
Node::Node(int x)
{
data = x;
next = NULL;
}
// Linkedlist class with helper functions
class LinkedList {
public:
Node* head;
LinkedList();
void insert(int x);
void reverse();
void traverse();
void sum(LinkedList*);
};
LinkedList::LinkedList()
{
head = NULL;
}
// Function to insert a node at
// the head of the list
void LinkedList::insert(int x)
{
Node* node = new Node();
node->data = x;
if (head == NULL)
head = node;
else {
node->next = head;
head = node;
}
}
// Function to reverse the linked list
void LinkedList::reverse()
{
Node *prev = NULL, *curr = head;
while (curr) {
Node* temp = curr->next;
curr->next = prev;
prev = curr;
curr = temp;
}
head = prev;
}
// Function to traverse and print the list
void LinkedList::traverse()
{
Node* temp = head;
while (temp) {
cout << temp->data << " -> ";
temp = temp->next;
}
cout << "NULL";
}
// Function to add two numbers
// represented as linked lists
void LinkedList::sum(LinkedList* l2)
{
reverse();
l2->reverse();
Node *start1 = head, *start2 = l2->head;
Node* prev = NULL;
int carry = 0;
// While both lists exist
while (start1 && start2) {
// Current sum
int temp = start1->data + start2->data + carry;
// Handle carry
start1->data = temp % 10;
carry = temp / 10;
prev = start1;
// Get to next nodes
start1 = start1->next;
start2 = start2->next;
}
// If there are remaining digits
// in any one of the lists
if (start1 || start2) {
if (start2)
prev->next = start2;
start1 = prev->next;
// While first list has digits remaining
while (start1) {
int temp = start1->data + carry;
start1->data = temp % 10;
carry = temp / 10;
prev = start1;
start1 = start1->next;
}
}
// If a new node needs to be
// created due to carry
if (carry > 0) {
prev->next = new Node(carry);
}
// Reverse the resultant list
reverse();
}
// Driver code
int main()
{
// Create first list
LinkedList* l1 = new LinkedList();
l1->insert(3);
l1->insert(6);
l1->insert(5);
// Create second list
LinkedList* l2 = new LinkedList();
l2->insert(2);
l2->insert(4);
l2->insert(8);
// Add the lists
l1->sum(l2);
// Print the resultant list
l1->traverse();
return 0;
}
Java
// Java implementation of the approach
import java.util.*;
class Node
{
int data;
Node next;
// constructor
Node(int d)
{
data = d;
next = null;
}
}// Node closes
class LinkedList
{
Node head;
// Helper function to traverse
void traverse(Node head)
{
while(head != null)
{
System.out.print(head.data + "->");
head = head.next;
}
}
// Helper function to insert data in linked list
void insert(int x)
{
Node temp = new Node(x);
if(head == null) head = temp;
else
{
temp.next = head;
head = temp;
}
}
// Helper function to reverse the list
public static Node reverse(Node head)
{
if(head == null || head.next == null) return head;
Node prev = null;
Node curr = head;
while(curr != null)
{
Node temp = curr.next;
curr.next = prev;
prev = curr;
curr = temp;
}
head = prev;
return head;
}
// Function to add two lists
public static Node sum(Node l1, Node l2)
{
if(l2 == null) return l1;
if(l1 == null) return l2;
// reverse l1 list
l1 = reverse(l1);
// reverse l2 list
l2 = reverse(l2);
// storing head whose reverse is to be returned
// This is where which will be final node
Node head = l1;
Node prev = null;
int c = 0,sum;
while(l1 != null && l2 != null)
{
sum = c + l1.data + l2.data;
l1.data = sum % 10;
c = sum / 10;
prev = l1;
l1 = l1.next;
l2 = l2.next;
}
if(l1 != null||l2 != null)
{
if(l2 != null) prev.next = l2;
l1 = prev.next;
while(l1 != null)
{
sum = c + l1.data;
l1.data = sum % 10;
c = sum / 10;
prev = l1;
l1 = l1.next;
}
}
if(c > 0) prev.next = new Node(c);
return reverse(head);
}
// Driver Code
public static void main(String[] args)
{
LinkedList l1 = new LinkedList();
l1.insert(3);
l1.insert(6);
l1.insert(5);
LinkedList l2 = new LinkedList();
l2.insert(2);
l2.insert(4);
l2.insert(8);
LinkedList l3 = new LinkedList();
Node head = sum(l1.head, l2.head);
l3.traverse(head);
System.out.print("Null");
}
}
// This code is contributed
// by Devarshi Singh
Python3
# Python3 implementation of the approach
# Linked List Node
class Node:
def __init__(self, data):
self.data = data
self.next = None
# Handle list operations
class LinkedList:
def __init__(self):
self.head = None
# Method to traverse list and
# return it in a format
def traverse(self):
linkedListStr = ""
temp = self.head
while temp:
linkedListStr += str(temp.data) + " -> "
temp = temp.next
return linkedListStr + "NULL"
# Method to insert data in linked list
def insert(self, data):
newNode = Node(data)
if self.head is None:
self.head = newNode
else:
newNode.next = self.head
self.head = newNode
# Helper function to reverse the list
def reverse(Head):
if (Head is None and
Head.next is None):
return Head
prev = None
curr = Head
while curr:
temp = curr.next
curr.next = prev
prev = curr
curr = temp
Head = prev
return Head
# Function to add two lists
def listSum(l1, l2):
if l1 is None:
return l1
if l2 is None:
return l2
# Reverse first list
l1 = reverse(l1)
# Reverse second list
l2 = reverse(l2)
# Storing head whose reverse
# is to be returned This is
# where which will be final node
head = l1
prev = None
c = 0
sum = 0
while l1 is not None and l2 is not None:
sum = c + l1.data + l2.data
l1.data = sum % 10
c = int(sum / 10)
prev = l1
l1 = l1.next
l2 = l2.next
if l1 is not None or l2 is not None:
if l2 is not None:
prev.next = l2
l1 = prev.next
while l1 is not None:
sum = c + l1.data
l1.data = sum % 10
c = int(sum / 10)
prev = l1
l1 = l1.next
if c > 0:
prev.next = Node(c)
return reverse(head)
# Driver code
linkedList1 = LinkedList()
linkedList1.insert(3)
linkedList1.insert(6)
linkedList1.insert(5)
linkedList2 = LinkedList()
linkedList2.insert(2)
linkedList2.insert(4)
linkedList2.insert(8)
linkedList3 = LinkedList()
linkedList3.head = listSum(linkedList1.head,
linkedList2.head)
print(linkedList3.traverse())
# This code is contributed by Debidutta Rath
C#
// C# implementation of the above approach
using System;
public class Node
{
public int data;
public Node next;
// constructor
public Node(int d)
{
data = d;
next = null;
}
}
// Node closes
public class LinkedList
{
Node head;
// Helper function to traverse
void traverse(Node head)
{
while(head != null)
{
Console.Write(head.data + "->");
head = head.next;
}
}
// Helper function to insert data in linked list
void insert(int x)
{
Node temp = new Node(x);
if(head == null) head = temp;
else
{
temp.next = head;
head = temp;
}
}
// Helper function to reverse the list
public static Node reverse(Node head)
{
if(head == null ||
head.next == null) return head;
Node prev = null;
Node curr = head;
while(curr != null)
{
Node temp = curr.next;
curr.next = prev;
prev = curr;
curr = temp;
}
head = prev;
return head;
}
// Function to add two lists
public static Node sum(Node l1, Node l2)
{
if(l2 == null) return l1;
if(l1 == null) return l2;
// reverse l1 list
l1 = reverse(l1);
// reverse l2 list
l2 = reverse(l2);
// storing head whose reverse is
// to be returned. This is where
// which will be final node
Node head = l1;
Node prev = null;
int c = 0,sum;
while(l1 != null && l2 != null)
{
sum = c + l1.data + l2.data;
l1.data = sum % 10;
c = sum / 10;
prev = l1;
l1 = l1.next;
l2 = l2.next;
}
if(l1 != null||l2 != null)
{
if(l2 != null) prev.next = l2;
l1 = prev.next;
while(l1 != null)
{
sum = c + l1.data;
l1.data = sum % 10;
c = sum / 10;
prev = l1;
l1 = l1.next;
}
}
if(c > 0) prev.next = new Node(c);
return reverse(head);
}
// Driver Code
public static void Main(String[] args)
{
LinkedList l1 = new LinkedList();
l1.insert(3);
l1.insert(6);
l1.insert(5);
LinkedList l2 = new LinkedList();
l2.insert(2);
l2.insert(4);
l2.insert(8);
LinkedList l3 = new LinkedList();
Node head = sum(l1.head, l2.head);
l3.traverse(head);
Console.Write("Null");
}
}
// This code is contributed by 29AjayKumar
Javascript
输出:
1 -> 4 -> 0 -> 5 -> NULL
时间复杂度: O(max(m, n)) 其中 m 和 n 分别是列表 l1 和列表 l2 中的节点数。
空间复杂度: O(1)
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。