复杂度
时间复杂度 O(n)
空间复杂度 O(n) 递归栈空间
思路
从末尾到首位,对两个单链表每一位数字对齐相加,再将结果用单链表表示出来即可。
技巧在于如何处理不同长度的数字,以及进位和最高位的判断。这里对于不同长度的数字,我们通过将较短的数字补0来保证每一位都能相加。
递归写法的思路比较直接,即判断该轮递归中两个ListNode是否为null。
- 全部为NULL时,返回进位值
- 有一个为NULL时,返回不为NULL的那个ListNode和进位相加的值
- 都不为NULL时,返回两个ListNode和进位相加的值
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
public class Solution {
public ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
return helper(l1,l2,0);
}
public ListNode* helper(ListNode* l1, ListNode* l2, int carry){
//l1和l2都为NULL时,判断进位值carry
//1.如果carry=0表示此时l1和l2都为空链,则返回NULL
//2.如果carry≠0,返回进位值
if(l1==NULL && l2==NULL){
return carry == 0? NULL : new ListNode(carry);
}
//有一个为NULL时,返回不为NULL的那个ListNode和进位相加的值
if(l1==NULL && l2!=NULL){
l1 = new ListNode(0);
}
if(l2==NULL && l1!=NULL){
l2 = new ListNode(0);
}
//都不为NULL时,返回两个ListNode和进位相加的值
int sum = l1.val + l2.val + carry;
//cur为该计算位,计算和结果可能>10,所以需要取模值
ListNode cur = new ListNode(sum % 10);
//将计算和结果的数返回到该位的下一位,保存到carry进位值中,留给下次递归使用
cur.next = helper(l1.next, l2.next, sum / 10);
//返回cur的头指针
return cur;
}
}
思路:
创建两个栈s1、s2,其中一个栈(s1)只管压栈数据,另一个栈(s2)出数据。所以问题就好解决了!需要考虑的就是什么时候从s2出栈。两种情况:
1.当s2为空栈时,需要将s1的数据全部倒过来,然后出栈s2。
2.当s2不为空栈时,直接从s2出栈。
最后从s2出的数据就是满足后进先出(队列)的特性。
class Solution
{
public:
//队列的Push插入元素
void push(int node) {
stack1.push(node);
}
//队列的Pop删除元素
int pop() {
int x;
if (stack2.empty()) //stack2为空时,将stack1元素逐个弹出并压入stack2,然后在弹出stack2的栈顶元素
{
while (!stack1.empty())
{
stack2.push(stack1.top());
stack1.pop();
}
x = stack2.top();
stack2.pop();
}
else //stack2不为空时,直接弹出stack2的栈顶元素
{
x = stack2.top();
stack2.pop();
}
return x;
}
private:
stack<int> stack1;
stack<int> stack2;
}