在leetcode上看了一个题目,对链表求和,之前是用字符串表示大数,进行求和,然后就写了下代码,顺便复习下链表的基本知识。
原题如下:
给出两个 非空 的链表用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字。如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。
您可以假设除了数字 0 之外,这两个数都不会以 0 开头。
示例:
输入:(2 -> 4 -> 3) + (5 -> 6 -> 4)
输出:7 -> 0 -> 8
原因:342 + 465 = 807
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/add-two-numbers
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
链表结构如下:
public class ListNode
{
public int val;
public ListNode next;
public ListNode(int x) { val = x; }
}
把数组元素转换成链表
public ListNode ConstructList(int[] array)
{
if(array == null)
{
return null;
}
ListNode root = null;
//链表头部插入
//for (int i = array.Length-1; i >= 0; --i)
//{
// ListNode tmp = new ListNode(array[i]);
// tmp.next = root;
// root = tmp;
//}
//链表尾插入
ListNode tail = null;
for (int i = 0; i < array.Length; ++i)
{
ListNode tmp = new ListNode(array[i]);
if (root == null)
{
root = tmp;
tail = root;
}
else
{
tail.next = tmp;
tail = tmp;
}
}
return root;
}
对链表元素求和, 核心思想: 每次计算时除了链表两个节点的元素相加,还要考虑上一次的进位;
public ListNode AddTwoNumbers(ListNode l1, ListNode l2)
{
ListNode newHead = null;
if (l1 == null)
{
newHead = l2;
}
else if (l2 == null)
{
newHead = l1;
}
else
{
ListNode tmp1 = l1;
ListNode tmp2 = l2;
ListNode curNode = null;
ListNode tail = null;
while (tmp1 != null || tmp2 != null)
{
int singleSum = 0;
if (tmp1 != null)
{
singleSum = tmp1.val;
tmp1 = tmp1.next;
}
if (tmp2 != null)
{
singleSum += tmp2.val;
tmp2 = tmp2.next;
}
int data0 = singleSum % 10;
int data1 = singleSum / 10;
if (curNode == null)
{
curNode = new ListNode(data0);
}
else
{
curNode.val += data0;
if (curNode.val >= 10)
{
data1 += 1;
curNode.val = curNode.val % 10;
}
}
if(newHead == null)
{
newHead = curNode;
tail = newHead;
}
else
{
tail.next = curNode;
tail = curNode;
}
if (data1 == 0) //不进位
{
curNode = null;
}
else //进了1位
{
curNode = new ListNode(data1);
}
}
if (curNode != null)
{
if(newHead == null)
{
newHead = curNode;
}
else
{
tail.next = curNode;
}
}
}
return newHead;
}
测试模块
public ToSum()
{
int[] array1 = new int[] { 1,8 };
ListNode list1 = ConstructList(array1);
PrintListNode(list1);
int[] array2 = null;// new int[] { 0 };
ListNode list2 = ConstructList(array2);
PrintListNode(list2);
ListNode res = AddTwoNumbers(list1, list2);
PrintListNode(res);
}
public void PrintListNode(ListNode root)
{
ListNode tmp = root;
while (tmp != null)
{
Console.Write(tmp.val + "\t");
tmp = tmp.next;
}
Console.WriteLine("END");
}
顺便复习一下链表翻转
ListNode ListReverse(ListNode newHead)
{
ListNode reverHead = null;
ListNode currentNode = newHead;
ListNode preCurNode = null;
while (currentNode != null)
{
ListNode tmp = currentNode.next;
if (tmp == null)
{
reverHead = currentNode;
}
currentNode.next = preCurNode;
preCurNode = currentNode;
currentNode = tmp;
}
return reverHead;
}