两数相加Ⅱ
题目来源:leetcode
1、问题描述
给你两个 非空 链表来代表两个非负整数。数字最高位位于链表开始位置。它们的每个节点只存储一位数字。将这两数相加会返回一个新的链表。 你可以假设除了数字 0 之外,这两个数字都不会以零开头。
2、思路解析
思路一:哈希+反转链表 将俩个链表节点分别存储在hash数据结构中然后从尾部遍历相加,将相加结果保存在sum中,然后申请新节点,将新节点插入到新链表中这样得到的是结果链表的反向链表。最后将链表反转就可以 思路二:反转链表相加+反转链表 先将两个链表反转,这样就比较容易相加,相加后将最后得到的链表也进行反转就行 思路三:栈+反转链表 先将链表分别入栈,因为栈是先进先出这就导致头节点先进去未结点先出来这就方便运算,每加一次就申请一次新节点,最后将新节点插入到新链表中,最后也需要将新链表反转才能得到结果链表
3、代码实现
class Solution {
public:
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
vector<int> v1;
vector<int> v2;
while(l1){
v1.push_back(l1->val);
l1=l1->next;
}
while(l2){
v2.push_back(l2->val);
l2=l2->next;
}
ListNode*proot=new ListNode(-1);
ListNode*root=proot;
int end1=v1.size()-1;
int end2=v2.size()-1;
int num=0;
while(end1>=0&&end2>=0){
int sum=v1[end1]+v2[end2]+num;
if(sum>=10){
sum-=10;
num=1;
}else{
num=0;
}
root->next=new ListNode(sum);
root=root->next;
end1--;
end2--;
}
while(end1>=0){
int sum=v1[end1]+num;
if(sum>=10){
sum-=10;
num=1;
}else{
num=0;
}
root->next=new ListNode(sum);
root=root->next;
end1--;
}
while(end2>=0){
int sum=v2[end2]+num;
if(sum>=10){
sum-=10;
num=1;
}else{
num=0;
}
root->next=new ListNode(sum);
root=root->next;
end2--;
}
if(num!=0){
root->next=new ListNode(num);
}
ListNode *cur=proot->next->next;
ListNode*node=proot->next;
node->next=NULL;
while(cur){
ListNode*node1=cur->next;
cur->next=node;
node=cur;
cur=node1;
}
return node;
}
};
class Solution {
public:
ListNode* FAN(ListNode*root){
ListNode*node1=root;
ListNode*node2=root->next;
node1->next=NULL;
while(node2){
ListNode*node=node2->next;
node2->next=node1;
node1=node2;
node2=node;
}
return node1;
}
ListNode* addInList(ListNode* head1, ListNode* head2) {
if(head1==NULL&&head2==NULL){
return NULL;
}
if(head1==NULL){
return head2;
}else if(head2==NULL){
return head1;
}
ListNode*node=FAN(head1);
ListNode*node1=FAN(head2);
ListNode*root=new ListNode(-1);
ListNode*cur=root;
int i=0;
int sum=0;
while(node&&node1){
sum=node->val+node1->val+i;
if(sum>=10){
sum-=10;
i=1;
}else{
i=0;
}
cur->next=new ListNode(sum);
cur=cur->next;
node=node->next;
node1=node1->next;
}
while(node){
sum=node->val+i;
if(sum>=10){
sum-=10;
i=1;
}else{
i=0;
}
cur->next=new ListNode(sum);
cur=cur->next;
node=node->next;
}
while(node1){
sum=node1->val+i;
if(sum>=10){
sum-=10;
i=1;
}else{
i=0;
}
cur->next=new ListNode(sum);
cur=cur->next;
node1=node1->next;
}
if(i==1){
cur->next=new ListNode(i);
}
ListNode*head=FAN(root->next);
return head;
}
};
四数相加
题目来源:Leetcode
1、问题描述
给你四个整数数组 nums1、nums2、nums3 和 nums4 ,数组长度都是 n ,请你计算有多少个元组 (i, j, k, l) 能满足: 0 <= i, j, k, l < n nums1[i] + nums2[j] + nums3[k] + nums4[l] == 0
2、思路解析
思路一:循环暴力破解 该思路简单容易理解,就是四个for循环遍历每中排列,然后判断是不是符合条件,符合条件就将结果保存在数组中。虽然思路简单,但是时间复杂度为O(N^4),随着数据量的增加运算时间也在不断增加。 思路二:哈希 将数组分成两组,数组A和数组B为一组,将A[i]+B[j]=sum结果保存在hashamap中充当键值,其出现次数为values,也就是双for循环遍历A数组和B数组将结果保存在map的键值中,将出现次数保存在values。数组C和数组D为一组,双for循环遍历数组C和数组D,寻找map中是不是存在-(C[i]+D[j])也就是sum,如果存在(也即是说出现sum+C[i]+D[j]0的情况,出现的次数N就是结果为C[i]+D[j]+sum0有N种情况)就将出现次数加起来,最后将次数相加的结果返回就行
3、代码实现
class Solution {
public:
int fourSumCount(vector<int>& nums1, vector<int>& nums2, vector<int>& nums3, vector<int>& nums4) {
int ret=0;
for(int i=0;i<nums1.size();i++){
for(int j=0;j<nums2.size();j++){
for(int n=0;n<nums3.size();n++){
for(int m=0;m<nums4.size();m++){
if(nums1[i]+nums2[j]+nums3[n]+nums4[m]==0){
ret++;
}
}
}
}
}
return ret++;
}
};
class Solution {
public:
int fourSumCount(vector<int>& nums1, vector<int>& nums2, vector<int>& nums3, vector<int>& nums4) {
unordered_map<int,int> m;
for(int i=0;i<nums1.size();i++){
for(int j=0;j<nums2.size();j++){
m[nums1[i]+nums2[j]]++;
}
}
int num=0;
for(int i=0;i<nums3.size();i++){
for(int j=0;j<nums4.size();j++){
if(m.count(-(nums3[i]+nums4[j]))){
num+=m[-(nums3[i]+nums4[j])];
}
}
}
return num;
}
};
|