合并相似的物品

题目

给你两个二维整数数组 items1 和 items2 ,表示两个物品集合。每个数组 items 有以下特质:

items[i] = [valuei, weighti] 其中 valuei 表示第 i 件物品的 价值 ,weighti 表示第 i 件物品的 重量 。
items 中每件物品的价值都是 唯一的 。
请你返回一个二维数组 ret,其中 ret[i] = [valuei, weighti], weighti 是所有价值为 valuei 物品的 重量之和 。

注意:ret 应该按价值 升序 排序后返回。

示例 1:

输入:items1 = [[1,1],[4,5],[3,8]], items2 = [[3,1],[1,5]]
输出:[[1,6],[3,9],[4,5]]
解释:
value = 1 的物品在 items1 中 weight = 1 ,在 items2 中 weight = 5 ,总重量为 1 + 5 = 6 。
value = 3 的物品再 items1 中 weight = 8 ,在 items2 中 weight = 1 ,总重量为 8 + 1 = 9 。
value = 4 的物品在 items1 中 weight = 5 ,总重量为 5 。
所以,我们返回 [[1,6],[3,9],[4,5]] 。
示例 2:

输入:items1 = [[1,1],[3,2],[2,3]], items2 = [[2,1],[3,2],[1,3]]
输出:[[1,4],[2,4],[3,4]]
解释:
value = 1 的物品在 items1 中 weight = 1 ,在 items2 中 weight = 3 ,总重量为 1 + 3 = 4 。
value = 2 的物品在 items1 中 weight = 3 ,在 items2 中 weight = 1 ,总重量为 3 + 1 = 4 。
value = 3 的物品在 items1 中 weight = 2 ,在 items2 中 weight = 2 ,总重量为 2 + 2 = 4 。
所以,我们返回 [[1,4],[2,4],[3,4]] 。
示例 3:

输入:items1 = [[1,3],[2,2]], items2 = [[7,1],[2,2],[1,4]]
输出:[[1,7],[2,4],[7,1]]
解释:
value = 1 的物品在 items1 中 weight = 3 ,在 items2 中 weight = 4 ,总重量为 3 + 4 = 7 。
value = 2 的物品在 items1 中 weight = 2 ,在 items2 中 weight = 2 ,总重量为 2 + 2 = 4 。
value = 7 的物品在 items2 中 weight = 1 ,总重量为 1 。
所以,我们返回 [[1,7],[2,4],[7,1]] 。

提示:

1 <= items1.length, items2.length <= 1000
items1[i].length == items2[i].length == 2
1 <= valuei, weighti <= 1000
items1 中每个 valuei 都是 唯一的 。
items2 中每个 valuei 都是 唯一的 。

收获

1:本周第一次参加力扣双周赛,初步体会到了自己对语言的应用还有很多欠缺,有自己的思想,但是和那些很简洁的思想还差好多,自己写了70多行,而大佬们只写10行就可以解决,我想我这个假期的锻炼就是尽可能缩小这之间的差距,写代码重要的是思想(开始最好能够想出一个简洁的思想实现也比较便捷,不要吝惜这一点点思考的时间),最后是直接实现,而自己目前思想不是很完善,并且写出来也有丢丢困难,都要不段学习,双管齐下,期待一个月以后的进展~
2:学会了对二维vector的输入、巩固了选择排序、适当使用了while i++;j++;的方法完成了本题
3:我的思想是先对每一个二维数组进行排序,之后对两个数组按照链表的思维进行合并(链表思维严重)
4:本题更好的思想是创建一个map映射,对两个vector数组,分别在对应的位置进行+的存储,最后在从头遍历合并输出~

代码

自己写的

#include <iostream>
#include <bits/stdc++.h>

using namespace std;

 vector<vector<int> > selectSort(vector<vector<int> >& items){
        int min;
        for(int i=0;i<items.size()-1;i++){
            min=i;
            for(int j=i+1;j<items.size();j++){
                if(items[j][0]<items[min][0])
                    min=j;
            }
            if(min!=i){
                swap(items[i],items[min]);
            }
        }
        return items;
    }

    vector<vector<int> > mergeSimilarItems(vector<vector<int> >& items1, vector<vector<int> >& items2) {
        items1=selectSort(items1);
        items2=selectSort(items2);
        /*for(int i=0;i<items1.size();i++){
            cout<<items1[i][0]<<items1[i][1];
        }
        for(int i=0;i<items2.size();i++){
            cout<<items2[i][0]<<items2[i][1];
        }*/
        vector<vector<int> > items3;
        int k=-1,i=0,j=0;
        while(1){
            k++;
            if(k==items1.size()+items2.size()){
                return items3;
            }
            if(i==items1.size()){
                for(int m=j;m<items2.size();m++)
                    items3.push_back(items2[m]);
                continue;
            }
            if(j==items2.size()){
                for(int m=i;m<items1.size();m++)
                    items3.push_back(items1[m]);
                continue;
            }
            if(items1[i][0]>items2[j][0]){
                    cout<<"j"<<j<<endl;
                    items3.push_back(items2[j]);
                    j++;
                    continue;
                }
            else if(items1[i][0]<items2[j][0]){
                    cout<<"i"<<i<<endl;
                    items3.push_back(items1[i]);
                    i++;
                    continue;
                    //k++;
            }
            else{
                vector<int> temp;
                temp.push_back(items2[i][0]);
                temp.push_back(items1[i][1]+items2[j][1]);
                items3.push_back(temp);
                i++;
                j++;
                //cout<<"i"<<i<<endl;
                continue;
               // k+=2;
            }

        }
        return items3;

    }

int main()
{
    vector<vector<int> > items1;
    vector<vector<int> > items2;
    vector<vector<int> > items3;
    vector<int> temp;
    int n1,n2;
    cin>>n1>>n2;
    for(int i=0;i<n1;i++){
        int temp1,temp2;
        temp.clear();
        cin>>temp1>>temp2;
        temp.push_back(temp1);
        temp.push_back(temp2);
        items1.push_back(temp);
    }
    for(int i=0;i<n2;i++){
        int temp1,temp2;
        temp.clear();
        cin>>temp1>>temp2;
         temp.push_back(temp1);
        temp.push_back(temp2);
        items2.push_back(temp);
    }
    items3=mergeSimilarItems(items1,items2);
    for(int i=0;i<(items1.size()+items2.size());i++){
        cout<<items3[i][0]<<items3[i][1];
    }
    return 0;
}

网上其他大神写的

vector<vector<int>> mergeSimilarItems(vector<vector<int>>& items1, vector<vector<int>>& items2) {
        map<int, int> mp;
        for (auto &vec : items1) mp[vec[0]] += vec[1];
        for (auto &vec : items2) mp[vec[0]] += vec[1];
        vector<vector<int>> ans;
        for (auto it = mp.begin(); it != mp.end(); it++) ans.push_back(vector<int>{it->first, it->second});
        return ans;
    }

作者:TsReaper
链接:https://leetcode.cn/circle/discuss/sT9OXv/view/Zep22v/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

————————————————————————————
后续补充map学习!

收获

1:自己重改最开始的链表思想,尝试着使用map方法进行学习,学会了它的简单遍历auto可以自动获得迭代器类型,使用mp.begin(),接下来++的方法可以对mp中的每一个映射进行遍历,最后一个位置是end(),同时对映射的访问,一个是it->first,一个是it->second,分别是访问下标和值
2:知道了map和unordered_map的区别,原来并不知道具体为什么是两个名字,原来unordered_map从名字上来看就已经知道了是没有顺序的~,同时后者更加适合查找,前者更加适合有序算法的实现,如果想要查找某一元素可以使用mp.find(x)!=mp.end()进行判断,只要找到的位置不是最终的位置就说明找到了,存在该元素就可以对mp.find(x)位置auto it mp.find(x),通过it查找对应的元素值,或者直接mp[x]就可以知道对应的值是多少了

#include <iostream>
#include <bits/stdc++.h>

using namespace std;

vector<vector<int > >mergeSimilarItems(vector<vector<int > >&items1,vector<vector<int > >&items2){
    map<int,int>mp;
    //此处不可以使用unordered_map,因为unordered_map对应的映射是无序的,其适合查找,但是不适合有排序需求的,所以需要使用map!
    vector<vector<int > >ans;
    for(int i=0;i<items1.size();i++){
        mp[items1[i][0]]+=items1[i][1];
    }
    for(int i=0;i<items1.size();i++){
        mp[items2[i][0]]+=items2[i][1];
    }
    for (auto it = mp.begin(); it != mp.end(); it++)
        ans.push_back(vector<int>{it->first, it->second});
    return ans;
}

int main()
{
    vector<vector<int > >items1;
    vector<vector<int > >items2;
    int value,weight;
    while(cin>>value>>weight){
        items1.push_back({value,weight});
        if(cin.get()=='\n'){
            break;
        }
    }
    while(cin>>value>>weight){
        items2.push_back({value,weight});
        if(cin.get()=='\n'){
            break;
        }
    }
    vector<vector<int > >items3=mergeSimilarItems(items1,items2);
    for(int i=0;i<items3.size();i++){
        cout<<items3[i][0]<<' '<<items3[i][1]<<endl;
    }
    return 0;
}

参考链接:
unordered_map 简介
觉得写的很好的文章~,使用案例也有,相应的扩展应用也有!

#include <iostream>  
#include <unordered_map>  
#include <map>
#include <string>  
using namespace std;  
int main()  
{  
	//注意:C++11才开始支持括号初始化
    unordered_map<int, string> myMap={{ 5, "张大" },{ 6, "李五" }};//使用{}赋值
    myMap[2] = "李四";  //使用[ ]进行单个插入,若已存在键值2,则赋值修改,若无则插入。
    myMap.insert(pair<int, string>(3, "陈二"));//使用insert和pair插入
  
	//遍历输出+迭代器的使用
    auto iter = myMap.begin();//auto自动识别为迭代器类型unordered_map<int,string>::iterator
    while (iter!= myMap.end())
    {  
        cout << iter->first << "," << iter->second << endl;  
        ++iter;  
    }  
	
	//查找元素并输出+迭代器的使用
    auto iterator = myMap.find(2);//find()返回一个指向2的迭代器
    if (iterator != myMap.end())
	    cout << endl<< iterator->first << "," << iterator->second << endl;  
    system("pause");  
    return 0;  
}  


练习
236. 二叉树的最近公共祖先

方法二:存储父节点

思路
我们可以用哈希表存储所有节点的父节点,然后我们就可以利用节点的父节点信息从 p 结点开始不断往上跳,并记录已经访问过的节点,再从 q 节点开始不断往上跳,如果碰到已经访问过的节点,那么这个节点就是我们要找的最近公共祖先。

算法

从根节点开始遍历整棵二叉树,用哈希表记录每个节点的父节点指针。

从 p 节点开始不断往它的祖先移动,并用数据结构记录已经访问过的祖先节点。

同样,我们再从 q 节点开始不断往它的祖先移动,如果有祖先已经被访问过,即意味着这是 p 和 q 的深度最深的公共祖先,即 LCA 节点。

class Solution {
public:
    unordered_map<int, TreeNode*> fa;
    unordered_map<int, bool> vis;
    void dfs(TreeNode* root){
        if (root->left != nullptr) {
            fa[root->left->val] = root;
            dfs(root->left);
        }
        if (root->right != nullptr) {
            fa[root->right->val] = root;
            dfs(root->right);
        }
    }
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
        fa[root->val] = nullptr;
        dfs(root);
        while (p != nullptr) {
            vis[p->val] = true;
            p = fa[p->val];
        }
        while (q != nullptr) {
            if (vis[q->val]) return q;
            q = fa[q->val];
        }
        return nullptr;
    }
};


作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/lowest-common-ancestor-of-a-binary-tree/solution/er-cha-shu-de-zui-jin-gong-gong-zu-xian-by-leetc-2/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
————————————————
版权声明:本文为CSDN博主「菠萝开方」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_40838478/article/details/114664223

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值