復習leetcode第二題:兩數相加

本文會給出筆者自己的解答(代碼較為冗余,其實就是屎山代碼)以及優秀代碼的解析

下圖是題目

b98ab95f90244322a1a09ac50efca748.png

解法1(筆者所使用的辦法):?

解題思路:

以下思路是基于示例1(上圖)思考的

步驟1:因為該函數只傳來了兩個鏈表的首元結點指針,所以我們不難想到可以創建一個新鏈表來存放兩鏈表相加的內容

步驟2:由于我們最后需要返回新鏈表的首元結點指針,而新鏈表不斷創建以后,用于創建鏈表的指針也后移了,因此我們還需要創建一個指針phead,用作最后的函數返回

步驟3:題目給我們的結構體名稱為Listnode(在注釋行寫了),筆者覺得大小寫切換太麻煩了,因此這邊改成了listnode

步驟4:通過示例1我們也不難發現,我們需要使用循環語句來多次讓兩個鏈表的結點內容相加,并存放到新鏈表中;而循環的退出條件應該是l1鏈表和l2鏈表的所有結點的數據全部相加完了,即l1、l2同時為空指針

上述步驟代碼如下:

/*** Definition for singly-linked list.* struct ListNode {*     int val;*     struct ListNode *next;* };*/typedef struct ListNode listnode;
listnode* buynode(int x) //用于創建新鏈表的函數{listnode* newnode = (listnode*)malloc(sizeof(listnode));newnode->val = x;newnode->next = NULL;return newnode;
}//l1首元結點指針      //l2首元結點指針
struct ListNode* addTwoNumbers(struct ListNode* l1, struct ListNode* l2) 
{int count=0;listnode* newnode=buynode(0); //創建一個新鏈表的首元結點,之后每次創建新鏈表都傳0值,因為只有給新鏈表結點0這個初值才不會影響結果//當然也并不是必須給新鏈表的結點賦初值,這里只是為了保險起見listnode* phead=newnode;while(l1||l2) //退出條件為兩個指針全為空指針{……;}return phead;
}

1f08a6952a6c4ca58a8f0183ef310a4c.png

示例1的情況:

示例1中出現了兩數相加等于10的情況,最后l1、l2結點所對應的新鏈表結點留下來的數據為0,然后把 1這個數值 進1位和后續結點數據內容相加,這也就導致了 4+3+1 = 8。但我們不難發現,l1、l2的結點數據相加最大值為18(即使加上1也只有19),因此只有可能把1這個數值進1位,不可能把1以外的數值進1位。?

因此我們可以進行一個分支語句,分為了最后l1、l2結點數據相加 大于等于10 小于等于9兩種情況;然后通過一個計數器count,來判斷是否需要對后一個結點數據加1

每次相加完,讓l1、l2、新鏈表都往后移動一位

代碼如下所示:

?

        //分為l1+l2 <=9 以及 l1+l2 >=10 兩種情況//<=9if((l1->val)+(l2->val)+count<=9) {newnode->val=(l1->val)+(l2->val)+count;count=0;}//>=10else{newnode->val=(l1->val)+(l2->val)+count-10;count=1;}l1=l1->next;l2=l2->next; newnode->next=buynode(0);newnode=newnode->next;

bcd5c9e8d2374ad2af6f20353d02538e.png

示例2的情況用示例1的代碼就能解決,此處不再講解。

f6607e7e89c5422dbc8b24a36c825832.png

示例3的情況:

該示例告訴我們,l1為空時,l2不一定為空;l2為空時,l1不一定為空。

因此,會有三種情況:分別是l1、l2都不為空,只有l1為空,只有l2為空。此處可以通過三條分支語句來解決。

當l1為空,l2不為空時,把l1繼續往后移動一位代碼會出錯(對空指針進行解引用操作),因此我們需要在不同的分支語句里面對不同情況進行不同的向后移位操作

而當把所有數據相加完,l1、l2都為空的時候,有可能count仍為1(示例3輸出里最后會出現一個1的原因),因此我們需要在整個循環語句后,解決這個問題。直接在新鏈表最后面加上一個結點,且最后一個結點數據域只可能為1(上文已經講解過只可能為1的原因)

代碼如下所示:

?

        if(l1&&l2) //兩指針都非空{//分為l1+l2 <=9 以及 l1+l2 >=10 兩種情況//<=9if((l1->val)+(l2->val)+count<=9) {newnode->val=(l1->val)+(l2->val)+count;count=0;}//>=10else{newnode->val=(l1->val)+(l2->val)+count-10;count=1;}l1=l1->next;l2=l2->next; }else if(l1) //l1還不為空的情況{if((l1->val)+count<=9){newnode->val=(l1->val)+count;count=0;}else{newnode->val=(l1->val)+count-10;count=1;}l1=l1->next; //為防止對空指針l2進行解引用操作}    else if(l2) //l2還不為空的情況{if((l2->val)+count<=9){newnode->val=(l2->val)+count;count=0;}else{newnode->val=(l2->val)+count-10;count=1;}l2=l2->next; //為防止對空指針l1進行解引用操作}  if(count==1) //兩個指針全都為空但count還是為1,是對示例3的解決{newnode->next=buynode(1); //直接在newnode指針最后面加上一個結點,且最后一個結點數據域只可能為1}  

由于新鏈表一直要創建到l1、l2都為空,那么在循環語句(循環語句退出條件為l1、l2都為空)里的新鏈表創建就不需要加以限制了呢?

答:如果不加以限制,會出現下圖的情況,這是由于在最后一次l1、l2結點數據相加并放入新鏈表以后,還會再進行一次新鏈表的結點創建

解決方法:

  1. 把新鏈表的首元結點的創建放在循環語句里面,并且在第一次創建新鏈表的結點時,把該結點賦給phead,并且所有操作都放在l1、l2結點數據相加之前
  2. 在循環語句末尾,給新鏈表的創建加上一條if語句,當l1、l2全為空指針,不再進行結點創建工作(筆者在此使用的)

4a886befb54f41dcb16ffdaa555f483c.png

        if(l1||l2) //只有兩指針還有需要存入的數據再開辟新的空間,如果都已經存放完畢,那么就無需再開辟新的{newnode->next=buynode(0);newnode=newnode->next;}

解法1全部代碼展示:

/*** Definition for singly-linked list.* struct ListNode {*     int val;*     struct ListNode *next;* };*/typedef struct ListNode listnode;
listnode* buynode(int x){listnode* newnode = (listnode*)malloc(sizeof(listnode));newnode->val = x;newnode->next = NULL;return newnode;
}//l1首元結點指針      //l2首元結點指針
struct ListNode* addTwoNumbers(struct ListNode* l1, struct ListNode* l2) 
{int count=0;listnode* newnode=buynode(0); //創建一個新鏈表的首元結點listnode* phead=newnode;while(l1||l2) //退出條件為兩個指針全為空{if(l1&&l2) //兩指針都非空{//分為l1+l2 <=9 以及 l1+l2 >=10 兩種情況//<=9if((l1->val)+(l2->val)+count<=9) {newnode->val=(l1->val)+(l2->val)+count;count=0;}//>=10else{newnode->val=(l1->val)+(l2->val)+count-10;count=1;}l1=l1->next;l2=l2->next; }else if(l1) //l1還不為空的情況{if((l1->val)+count<=9){newnode->val=(l1->val)+count;count=0;}else{newnode->val=(l1->val)+count-10;count=1;}l1=l1->next; //為防止對空指針l2進行解引用操作}    else if(l2) //l2還不為空的情況{if((l2->val)+count<=9){newnode->val=(l2->val)+count;count=0;}else{newnode->val=(l2->val)+count-10;count=1;}l2=l2->next; //為防止對空指針l1進行解引用操作}    if(l1||l2) //只有兩指針還有需要存入的數據再開辟新的空間,如果都已經存放完畢,那么就無需再開辟新的{newnode->next=buynode(0);newnode=newnode->next;}}if(count==1) //兩個指針全都為空但count還是為1,是對示例3的解決{newnode->next=buynode(1); //直接在newnode指針最后面加上一個結點,且最后一個結點數據域只可能為1}return phead;
}

1eb04a4521f04ef3be2c8e8d44f01e2a.png


解法2(優秀代碼):
?

下面的代碼是leetcode官方給的C語言題解,好漂亮的代碼!

struct ListNode* addTwoNumbers(struct ListNode* l1, struct ListNode* l2) {struct ListNode *head = NULL, *tail = NULL;int carry = 0;while (l1 || l2) {int n1 = l1 ? l1->val : 0;int n2 = l2 ? l2->val : 0;int sum = n1 + n2 + carry;if (!head) {head = tail = malloc(sizeof(struct ListNode));tail->val = sum % 10;tail->next = NULL;} else {tail->next = malloc(sizeof(struct ListNode));tail->next->val = sum % 10;tail = tail->next;tail->next = NULL;}carry = sum / 10;if (l1) {l1 = l1->next;}if (l2) {l2 = l2->next;}}if (carry > 0) {tail->next = malloc(sizeof(struct ListNode));tail->next->val = carry;tail->next->next = NULL;}return head;
}

上述代碼解釋:

官方題解也是通過創建一個新鏈表,然后解決問題

首先創建了兩個指針,一個指向了首元結點(用作返回),一個指向了尾元結點(用作存放數據);carry和我代碼中的count一樣,都是保存多出來的那個1的

循環語句退出條件、分支語句的寫法此處省略

l1 ? l1->val : 0 --->該操作符的作用:l1不為空指針,就留下l1的值;l1為空指針,就留下0

l2 ? l2->val : 0 --->作用同上

sum:就是l1、l2的結點數據(還有carry)相加后結果

!head:如果頭指針為空指針為真(首元結點的創建,和首元結點地址的保留)

sum%10:對10取余

sum/10:整型相除

進行完對新鏈表的賦值操作以后,讓新鏈表的尾元結點指針指向空指針,等待下一次使用

最后如果carry依舊為1,那么再開辟一個結點空間存放,最后返回head指針

?

?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/19526.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/19526.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/19526.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

2024年終端安全管理系統最新排名(2024終端安全管理軟件TOP5)

在2024年&#xff0c;隨著企業數字化轉型的加速和網絡安全威脅的日益嚴峻&#xff0c;終端安全管理系統的重要性愈發凸顯。終端作為企業數據交互的關鍵節點&#xff0c;其安全性直接關系到企業的運營和數據的完整性。因此&#xff0c;各大終端安全管理系統廠商紛紛推出新的產品…

基于Vue+Node.js的購物網站設計與實現-計算機畢業設計源碼28500

摘 要 近年來&#xff0c;隨著移動互聯網的快速發展&#xff0c;電子商務越來越受到網民們的歡迎&#xff0c;電子商務對國家經濟的發展也起著越來越重要的作用。簡單的流程、便捷可靠的支付方式、快捷暢通的物流快遞、安全的信息保護都使得電子商務越來越贏得網民們的青睞。現…

數據庫系統概念(第七周 第一堂)(E-R模型)

目錄 前言 基本概念 觀點與模型 作用與要求 E-R模型元素 實體&#xff08;entity&#xff09; 實體集&#xff08;entity set&#xff09; 屬性&#xff08;attribute&#xff09; 域&#xff08;domain&#xff09; 碼 &#xff08;key&#xff09; 聯系 &#x…

虛擬現實環境下的遠程教育和智能評估系統(五)

查閱相關VR眼動注意力聯合教育學相關論文 1.Exploring Eye Gaze Visualization Techniques for Identifying Distracted Students in Educational VR&#xff08;IEEE VR 2020&#xff09; 摘要&#xff1a;我們提出了一種架構&#xff0c;使VR教學代理能夠響應眼動追蹤監控…

Android HIDL接口添加

一.HIDL介紹 HIDL的全稱是HAL interface definition language&#xff08;硬件抽象層接口定義語言&#xff09;&#xff0c;是Android Framework 與Android HAL之間的接口。HIDL 旨在用于進程間通信 (IPC)&#xff0c;進程之間的通信 采用 Binder 機制。 二.HIDL 與AIDL 的對…

JVM之【運行時數據區1】

JVM簡圖 運行時數據區簡圖 一、程序計數器&#xff08;Program Counter Register&#xff09; 1.程序計數器是什么&#xff1f; 程序計數器是JVM內存模型中的一部分&#xff0c;它可以看作是一個指針&#xff0c;指向當前線程所執行的字節碼指令的地址。每個線程在執行過程中…

Python魔法之旅-魔法方法(04)

目錄 一、概述 1、定義 2、作用 二、主要應用場景 1、構造和析構 2、操作符重載 3、字符串和表示 4、容器管理 5、可調用對象 6、上下文管理 7、屬性訪問和描述符 8、迭代器和生成器 9、數值類型 10、復制和序列化 11、自定義元類行為 12、自定義類行為 13、類…

Tensorflow入門實戰 P02-彩色圖片分類

目錄 1、序言 2、主要代碼 3、運行結果展示 &#xff08;1&#xff09;展示cifar10里面的20張圖片 &#xff08;2&#xff09;預測的圖片 &#xff08;3&#xff09;模型評估 本文為&#x1f517;365天深度學習訓練營 中的學習記錄博客&#x1f356; 原作者&#xff1a;K…

postgressql——ReadBuffer_common函數(7)

PostgreSQL中ReadBuffer_common函數 數據結構 BufferDesc 共享緩沖區的共享描述符(狀態)數據 typedef struct BufferDesc {//buffer tagBufferTag tag; /* ID of page contained in buffer *///buffer索引編號(0開始)int buf_id; /* buffers i…

大語言模型(一)OLMo

一、簡介 OLMo 是由AI2 發布的大語言模型以及構建框架,與大多數之前的嘗試只發布模型權重和推理代碼不同,OLMo 開源了整個框架,包括訓練數據、訓練代碼以及模型評估代碼。 OLMo框架包括構建和研究語言模型所需的工具和資源。對于訓練和建模,它包括完整的模型權重、訓練代…

SZJG-離線環境成功安裝Python和pip

在離線環境下安裝Python和pip&#xff0c;可以按照以下步驟進行。假設你已經下載了Python的安裝包 (Python-3.10.13.tgz)。 步驟 1&#xff1a;準備安裝包 將 Python-3.10.13.tgz 拷貝到目標機器上的一個目錄中&#xff0c;例如 /home/user/。 步驟 2&#xff1a;解壓安裝包…

4萬字長文讓人看懂ElementUI面試題及參考答案

ElementUI是什么?請簡述其主要特點。 ElementUI是一個基于Vue.js的桌面端組件庫,由餓了么團隊開發并維護。它旨在為開發人員提供一套用于構建網頁應用程序的高質量UI組件。ElementUI遵循Vue.js的設計思想,使得開發者可以快速地構建出風格統一、功能豐富的界面。 主要特點:…

水經微圖PC版4.3.10發布

讓GIS更簡單高效&#xff0c;讓地圖更豐富及時&#xff01; 水經微圖&#xff08;以下簡稱“微圖”&#xff09;新版已上線&#xff0c;在該版本中主要新增了天地圖歷史影像查看功能&#xff0c;以及其它功能的優化。 當前版本 當前版本號為&#xff1a;4.3.10 如果你發現該…

Pytorch反向傳播算法(Back Propagation)

一&#xff1a;revise 我們在最開始提出一個線性模型。 x為我們的輸入&#xff0c;w為權重。相乘的結果是我們對y的預測值。 那我們在訓練時就是對這個權重w進行更新&#xff0c;就需要用到上一章提到的梯度下降算法&#xff0c;不斷更新w。但是此時注意不是用y的預測值對w進…

linux centos nfs掛載兩臺服務器掛載統一磁盤目錄權限問題

查看用戶id id 用戶名另一臺為 修改uid和gid為相同id&#xff0c;添加附加組 usermod -u500 -Gwheel epms groupmod -g500 epms

網絡協議。

一、流程案例 接下來揭秘我要說的大事情&#xff0c;“雙十一”。這和我們要講的網絡協議有什么關系呢&#xff1f; 在經濟學領域&#xff0c;有個倫納德里德&#xff08;Leonard E. Read&#xff09;創作的《鉛筆的故事》。這個故事通過一個鉛筆的誕生過程&#xff0c;來講述…

[代碼復現]Self-Attentive Sequential Recommendation(ing)

參考代碼&#xff1a;SASRec.pytorch 可參考資料&#xff1a;SASRec代碼解析 前言&#xff1a;文中有疑問的地方用?表示了。可以通過ctrlF搜索’?。 環境 conda create -n SASRec python3.9 pip install torch torchvision因為我是mac運行的&#xff0c;所以device是mps 下面…

算法(七)插入排序

文章目錄 插入排序簡介代碼實現 插入排序簡介 插入排序&#xff08;insertion sort)是從第一個元素開始&#xff0c;該元素就認為已經被排序過了。然后取出下一個元素&#xff0c;從該元素的前一個索引下標開始往前掃描&#xff0c;比該值大的元素往后移動。直到遇到比它小的元…

Caliburn.Micro框架學習筆記——Action的參數傳遞機制

據此篇文章&#xff0c;我們繼續來談談Caliburn.Mirco的Action參數傳遞機制。因此程序結構都是默認MVVM的形式。 基本機制 它的機制是—— Caliburn.Micro 的智能對象參數綁定機制通過約定和反射使得視圖和視圖模型之間的交互變得更加直觀和簡潔。通過 cal:Message.Attach 語…

【C語言】探索文件讀寫函數的全貌

&#x1f308;個人主頁&#xff1a;是店小二呀 &#x1f308;C語言筆記專欄&#xff1a;C語言筆記 &#x1f308;C筆記專欄&#xff1a; C筆記 &#x1f308;喜歡的詩句:無人扶我青云志 我自踏雪至山巔 &#x1f525;引言 本章將介紹文件讀取函數的相關知識和展示使用場景&am…