599.两个列表的最小索引总和

博客围绕LeetCode 599题“两个列表的最小索引总和”展开。题目是找出Andy和Doris共同喜爱且索引和最小的餐厅。给出示例及提示,解题思路是用map存储字符串和索引,先遍历第一个列表存入map,再根据第二个列表元素在map中的情况判断并更新最小索引,还提及用Python实现。

599.两个列表的最小索引总和

题目描述

假设Andy和Doris想在晚餐时选择一家餐厅,并且他们都有一个表示最喜爱餐厅的列表,每个餐厅的名字用字符串表示。

你需要帮助他们用最少的索引和找出他们共同喜爱的餐厅。 如果答案不止一个,则输出所有答案并且不考虑顺序。 你可以假设总是存在一个答案。

示例 1:
输入:
[“Shogun”, “Tapioca Express”, “Burger King”, “KFC”]
[“Piatti”, “The Grill at Torrey Pines”, “Hungry Hunter Steakhouse”, “Shogun”]
输出: [“Shogun”]
解释: 他们唯一共同喜爱的餐厅是“Shogun”。

示例 2:
输入:
[“Shogun”, “Tapioca Express”, “Burger King”, “KFC”]
[“KFC”, “Shogun”, “Burger King”]
输出: [“Shogun”]
解释: 他们共同喜爱且具有最小索引和的餐厅是“Shogun”,它有最小的索引和1(0+1)。
提示:

两个列表的长度范围都在 [1, 1000]内。
两个列表中的字符串的长度将在[1,30]的范围内。
下标从0开始,到列表的长度减1。
两个列表都没有重复的元素。

解题思路

  • 考虑用一个map来存储字符串和对应的索引
  • 先遍历第一个列表,存入map。对于第二个列表中的每个字符串,根据在map中是否出现过来做判断
  • 如果出现过,再进一步根据索引之和,更新最小索引
class Solution {
public:
    vector<string> findRestaurant(vector<string>& list1, vector<string>& list2) {
        vector<string> ans;
        unordered_map<string,int>mp;
        for(int i=0;i<list1.size();i++){
            mp[list1[i]]=i+1;
        }
        int minidx = INT_MAX;
        for(int i=0;i<list2.size();i++){
            if(mp[list2[i]]!=0 ){
                if(mp[list2[i]]+i<minidx){
                    minidx = mp[list2[i]]+i;
                    ans.clear();
                    ans.push_back(list2[i]);    
                }else if(mp[list2[i]]+i==minidx){
                    ans.push_back(list2[i]);    
                }
            }
        }
        return ans;
    }
};
Python
class Solution(object):
    def findRestaurant(self, list1, list2):
        """
        :type list1: List[str]
        :type list2: List[str]
        :rtype: List[str]
        """
        ans = []
        book = {}
        minidx = 1e8
        for i, s in enumerate(list1):
            book[s] = i+1
            
        for i, s in enumerate(list2):
            if s in book:
                if book[s] + i < minidx:
                    minidx = book[s] + i
                    ans = [s]
                elif book[s] + i == minidx:
                    ans.append(s)        
                    
        return ans
        
随着信息技术在管理上越来越深入而广泛的应用,作为学校以及一些培训机构,都在用信息化战术来部署线上学习以及线上考试,可以与线下的考试有机的结合在一起,实现基于SSM的小码创客教育教学资源库的设计与实现在技术上已成熟。本文介绍了基于SSM的小码创客教育教学资源库的设计与实现的开发全过程。通过分析企业对于基于SSM的小码创客教育教学资源库的设计与实现的需求,创建了一个计算机管理基于SSM的小码创客教育教学资源库的设计与实现的方案。文章介绍了基于SSM的小码创客教育教学资源库的设计与实现的系统分析部分,包括可行性分析等,系统设计部分主要介绍了系统功能设计和数据库设计。 本基于SSM的小码创客教育教学资源库的设计与实现有管理员,校长,教师,学员四个角色。管理员可以管理校长,教师,学员等基本信息,校长角色除了校长管理之外,其他管理员可以操作的校长角色都可以操作。教师可以发布论坛,课件,视频,作业,学员可以查看和下载所有发布的信息,还可以上传作业。因而具有一定的实用性。 本站是一个B/S模式系统,采用Java的SSM框架作为开发技术,MYSQL数据库设计开发,充分保证系统的稳定性。系统具有界面清晰、操作简单,功能齐全的特点,使得基于SSM的小码创客教育教学资源库的设计与实现管理工作系统化、规范化。
为了将一个包含 `2N` 个元素的数组划分为两个大小各为 `N` 的子数组,使得这两个子数组的和之差最小,可以采用贪心算法或者动态规划来解决。以下是一个基于贪心思想的实现方法。 ### 思路 1. **排序与贪心选择**:首先对数组进行排序,然后从中间开始,尝试通过调整划分位置来最小化两部分的和的差。 2. **滑动窗口法**:使用双指针技术,从数组两端向中间移动,分别计算左右两部分的和,并调整指针以缩小两者之间的差距。 3. **递归优化**:如果需要更精确的结果,可以结合回溯或 DFS 来探索所有可能的划分方式,从而找到最优解。 ### 示例代码 ```cpp #include <iostream> #include <vector> #include <algorithm> #include <cmath> using namespace std; // 计算两个子数组和的最小差值划分 pair<vector<int>, vector<int>> minDifferencePartition(vector<int>& nums) { int n = nums.size() / 2; sort(nums.begin(), nums.end()); // 排序以便于贪心策略应用 vector<int> left, right; int sumLeft = 0, sumRight = 0; // 初始分配,前n个给left,后n个给right for (int i = 0; i < n; ++i) { left.push_back(nums[i]); sumLeft += nums[i]; } for (int i = n; i < 2 * n; ++i) { right.push_back(nums[i]); sumRight += nums[i]; } int minDiff = abs(sumLeft - sumRight); // 尝试交换元素以减少差值 for (int i = 0; i < n; ++i) { for (int j = n; j < 2 * n; ++j) { int newSumLeft = sumLeft - nums[i] + nums[j]; int newSumRight = sumRight + nums[i] - nums[j]; int diff = abs(newSumLeft - newSumRight); if (diff < minDiff) { // 更新最小差值及相关数组 minDiff = diff; swap(left[i], right[j - n]); // 注意索引偏移 sumLeft = newSumLeft; sumRight = newSumRight; } } } return {left, right}; } int main() { vector<int> nums = {3, 1, 4, 2, 5, 6}; // 示例输入 auto result = minDifferencePartition(nums); cout << "Left array: "; for (int num : result.first) { cout << num << " "; } cout << endl; cout << "Right array: "; for (int num : result.second) { cout << num << " "; } cout << endl; return 0; } ``` ### 说明 - **排序**:通过排序可以更好地应用贪心策略,因为较大的数更容易影响总和的变化。 - **初始划分**:将前 `N` 个元素分配到第一个子数组,剩下的分配到第二个子数组。 - **交换优化**:遍历所有可能的交换组合,寻找能使和的差值最小化的交换操作。 - **时间复杂度**:最坏情况下为 O(N²),适用于中等规模的数据集。 ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值