1、给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。请你将两个数相加,并以相同形式返回一个表示和的链表。你可以假设除了数字 0 之外,这两个数都不会以 0 开头。
示例:输入:l1 = [2,4,3], l2 = [5,6,4] 输出:[7,0,8] 解释:342 + 465 = 807.
该题主要是链表的相加,比较简单。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
ListNode*head=nullptr, *tail=nullptr;
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 = new ListNode(sum%10);
}else{
tail->next = new ListNode(sum%10);
tail = tail->next;
}
carry = sum/10;
if(l1){
l1=l1->next;
}
if(l2){
l2=l2->next;
}
if (carry>0){
tail->next = new ListNode(carry);
}
}
return head;
}
};
时间复杂度O(max(m,n)),取决于最长的链表长度;空间复杂度为O(1)。
但下面是更加简单易懂的一种代码:
class Solution {
public:
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
ListNode*head=new ListNode(-1);
ListNode*cur = head;
int c=0;
while(l1||l2||c){
int n1=l1?l1->val:0;
int n2=l2?l2->val:0;
ListNode*node= new ListNode((n1+n2+c)%10);
cur->next = node;
cur = node;
l1=l1?l1->next:nullptr;
l2=l2?l2->next:nullptr;
c=(n1+n2+c)/10;
}
return head->next;
}
};
2、给定一个只包括 '(',')','{','}','[',']' 的字符串 s ,判断字符串是否有效。有效字符串需满足:左括号必须用相同类型的右括号闭合。
左括号必须以正确的顺序闭合。示例:输入:s = "()" 输出:true
这个是一个典型的用栈实现括号匹配的问题,这里主要用到栈和哈希表的知识。
class Solution {
public:
bool isValid(string s) {
int n =s.size();
if(n%2==1){ //排除奇数个括号
return false;
}
unordered_map<char,char>pairs={
{')','('},
{']','['},
{'}','{'}
};
stack<char>stk;
for(char bian:s){
if(pairs.count(bian)){
if(stk.empty()||stk.top()!=pairs[bian]){
return false;
}
stk.pop();
}else{
stk.push(bian);
}
}
return stk.empty();
}
};
时间复杂度为O(n),是字符串遍历的长度。空间复杂度O(n+字符集的数量),因为这个涉及到栈的大小以及哈希表所使用的空间。