1.問題の説明:
空でない2つのリンクリストは、2つの負でない整数を表すために指定されています。それらの中で、それらのそれぞれの数字は逆の順序で保存され、それらの各ノードは1つの数字しか保存できません。これら2つの数値を加算すると、それらの合計を表す新しいリンクリストが返されます。数字の0を除いて、これらの数字のどちらも0で始まらないと想定できます。
例:
入力:(2-> 4-> 3)+(5-> 6-> 4)
出力:7-> 0-> 8
理由:342 + 465 = 807
ソース:
リンク(LeetCode):https: //leetcode-cn.com/problems/add-two-numbers
2.思考分析:
①まず質問の意味を理解することです。質問は主に2つのリンクリストの対応する位置を左から右に追加した結果を解決するため、比較的簡単に理解できます。ループで2つのリンクリストをたどります。 2つのリンクリストのいずれかが空でない場合、9-> 9 + 1などの状況が発生する可能性があるため、ループが実行され、両方のリンクリストが空のときに処理が完了します。生成されるノードの前のノードを表すListNodeタイプの変数。この変数を使用して要素を接続すると、より便利になります。
②変数を使用して最後のキャリーを記録し、リンクリストをトラバースしながら2つのリンクリストの対応する位置に要素を追加し、同時にキャリー変数の値を更新できます。リンクリストの1つが空の場合、他のリンクリストのみが更新されます。キャリーの状況と比較できます。最後に、キャリーが1かどうかを判断します。1の場合は、新しいノードを作成する必要があります。以前はキャリーであるため、ノードを接続する必要があります。プロセス全体は比較的簡単に理解できます。
③上記の新しいノードに加えて、それを最適化することもできます。リンクリストの新しいノードを作成できないように、元のリンクリストの値を変更するだけで済みます。ListNodeを使用して先行ノードを記録します。これは、リンクリストが空の場合に適していますpreの次のポインターフィールドを別のリンクリスト(2つのリンクリストには長さがあります)に接続し、ループ内の他のリンクリストの値とキャリーを更新し、最後に最後のキャリーを処理します。
3.コードは次のとおりです。
class Solution{
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
int carry = 0;
if (l1 == null && l2 == null) return null;
if (l1 == null && l2 != null) return l2;
if (l1 != null && l2 == null) return l1;
ListNode pre = null;
ListNode head = null;
while (l1 != null || l2 != null){
/*即将要插入的节点*/
ListNode newNode;
if(l1 != null && l2 != null){
int curVal = l1.val + l2.val + carry;
carry = curVal / 10;
newNode = new ListNode(curVal % 10);
if (pre == null){
pre = newNode;
head = newNode;
}
else {
pre.next = newNode;
pre = newNode;
}
l1 = l1.next;
l2 = l2.next;
}
else if (l1 != null){
int curVal = l1.val + carry;
carry = curVal / 10;
newNode = new ListNode(curVal % 10);
if (pre == null) {
pre = newNode;
head = newNode;
}
else {
pre.next = newNode;
pre = newNode;
l1 = l1.next;
}
}else if (l2 != null){
int curVal = l2.val + carry;
carry = curVal / 10;
newNode = new ListNode(curVal % 10);
if (pre == null) {
pre = newNode;
head = newNode;
}
else {
pre.next = newNode;
pre = newNode;
l2 = l2.next;
}
}
}
if (carry == 1){
ListNode last = new ListNode(1);
pre.next = last;
}
return head;
}
}
最適化されたコード:
class Solution{
public static ListNode addTwoNumbers(ListNode l1, ListNode l2) {
int carry = 0;
if (l1 == null && l2 == null) return null;
if (l1 == null && l2 != null) return l2;
if (l1 != null && l2 == null) return l1;
ListNode pre = null, head = l1;
int curVal = 0;
while (l1 != null && l2 != null){
curVal = l1.val + l2.val + carry;
l1.val = curVal % 10;
carry = curVal / 10;
/*pre指针是为了避免l1比较短的情况*/
pre = l1;
l1 = l1.next;
l2 = l2.next;
}
while (l1 != null){
curVal = l1.val + carry;
l1.val = curVal % 10;;
carry = curVal / 10;
pre = l1;
l1 = l1.next;
}
if (l1 == null && l2 != null) pre.next = l2;
while (l2 != null){
curVal = l2.val + carry;
l2.val = curVal % 10;
carry = curVal / 10;
pre = l2;
l2 = l2.next;
}
if (carry == 1) {
ListNode last = new ListNode(1);
pre.next = last;
}
return head;
}
}