两个列表的最小索引总和

Suppose Andy and Doris want to choose a restaurant for dinner, and they both have a list of favorite restaurants represented by strings.

You need to help them find out their common interest with the least list index sum. If there is a choice tie between answers, output all of them with no order requirement. You could assume there always exists an answer.

Example 1:

Input:
["Shogun", "Tapioca Express", "Burger King", "KFC"]
["Piatti", "The Grill at Torrey Pines", "Hungry Hunter Steakhouse", "Shogun"]
Output: ["Shogun"]
Explanation: The only restaurant they both like is "Shogun".

 

Example 2:

Input:
["Shogun", "Tapioca Express", "Burger King", "KFC"]
["KFC", "Shogun", "Burger King"]
Output: ["Shogun"]
Explanation: The restaurant they both like and have the least index sum is "Shogun" with index sum 1 (0+1).

 

Note:

  1. The length of both lists will be in the range of [1, 1000].
  2. The length of strings in both lists will be in the range of [1, 30].
  3. The index is starting from 0 to the list length minus 1.
  4. No duplicates in both lists.

 

题意:返回两个string数组中出现的,相同的且下标和最小的string,如果有多个这样的string,要把它们全部输出
思路:将数组1放入哈希表中,然后遍历数组2,如果有相同的就计算索引和,如果比之前的索引和小,那么更新最小索引和,并且清空结果数组,如果和之前的相等,就将其插入到结果数组中。
//将list1放入map中,遍历list2,如果有相同的就计算索引和
//if<之前的,更新索引和,清空ans,并将该字符串插入ans
//if==之前的,就插入ans

class Solution {
public:
    vector<string> findRestaurant(vector<string>& list1, vector<string>& list2) {
        unordered_map<string,int> m;
        vector<string> ans;
        int sum=list1.size()+list2.size();
        for(int i=0;i<list1.size();i++){
            m[list1[i]]=i;
        }
        for(int i=0;i<list2.size();i++){
            if(m.count(list2[i])){
                int temp=i+m[list2[i]];
                if(temp<sum){
                    sum=temp;
                    ans.clear();
                    ans.push_back(list2[i]);
                }   
                else if(temp==sum){
                    ans.push_back(list2[i]);
                }
            }
        }
        return ans;   
    }
};

 

 

转载于:https://www.cnblogs.com/Bipolard/p/9994479.html

<think>嗯,我现在得解决这个问题,题目是找出数组中两个索引,它们的元素之和等于特定值。然后返回升序排列的这两个索引,如果有多个的话,选小索引最小的那个。比如例子里的数组[1,2,3,-2,5,7],总和是7,返回的是[1,4],也就是2+5=7的情况。那我得仔细想怎么实现这个。 首先,我得理解题目要求。输入是数组长度、数组元素、特定值。输出两个索引,按升序排列。如果有多个解的话,要选其中第一个索引最小的那个。比如如果有两个解,比如索引对(0,5)和(1,2),那么应该选0较小的那个。但如果有多个解的第一个索引相同的话,可能要看第二个索引更小的?或者题目中的“索引对中小索引最小”具体怎么理解?比如,比如索引对(1,4)和(1,3),这时候应该选哪个?应该选第二个索引更小的那个吗?题目中的描述是“若有多组符合情况则输出索引对中小索引最小的一组”,这里的“小索引”可能指的是整个索引对中最小的那个?比如比如,比如两个解是(0,5)和(1,2),那么0和1中的最小是0,所以选第一个。如果是(1,3)和(2,3),那么最小索引分别是1和2,所以选前者。那这种情况下,我们的遍历方式应该按顺序找到第一个满足条件的对,然后返回。 那解决问题的思路应该是怎样的呢?最直接的方法是双重循环遍历所有可能的两个元素的和,找到第一个符合条件的索引对。然后返回升序排列后的结果。因为一旦找到第一个满足条件的,按照题目中的条件,如果有多个解,那么第一个被找到的应该就是小索引最小的。例如,当外层循环i从0开始,内层循环j从i+1开始,这样一旦找到nums[i] + nums[j]等于目标值,就返回i和j,因为此时i是可能的最小值,并且j也是i之后的最小可能的。这样就能满足题目中的条件。因为如果有多个解,例如当i=0时可能有多个j满足,此时i是0,是所有可能解中最小的i,所以直接返回第一个遇到的即可。或者,如果i=0的时候没有解,i=1的时候找到j,这时候就是下一个可能的最小解。所以双重循环的顺序应该可以保证正确的结果。 那接下来,如何实现这个逻辑呢? 首先,输入的处理。需要读入数组长度n,然后读入数组元素。接着读入目标值target。然后遍历所有可能的i和j的组合,i从0到n-2,j从i+1到n-1。计算两者的和是否等于target。一旦找到第一个符合条件的对,就记录i和j,然后立即返回。这样就能保证索引对的小索引最小的,因为外层循环i是按从小到大的顺序遍历的,而内层j也是从i+1开始,所以当找到一个解时,i是尽可能小的,而j也是i之后的最小的可能,所以整个索引对的升序排列是i和j,所以直接输出i和j的顺序即可。 例如,在例子中,数组是[1,2,3,-2,5,7]。目标值是7。遍历i=0时,检查j=1到5。i=0时,数组元素是1,那么找是否有元素等于7-1=6。数组中的元素是2、3、-2、5、7。对应的索引是1到5。那么当j=4时,元素是5,1+5=6?哦,原例子的总和是7。原例子的输出是索引1和4,对应的元素是2和5,总和是7。所以可能我之前的分析有问题,或者例子中的总和是7,所以目标值是7。这时候,当i=1,元素是2,那么需要找7-2=5。然后在数组中i=1后面的元素中找有没有5。数组中的元素是3,-2,5,7。对应的索引是2到5。当j=4的时候,元素是5,所以i=1,j=4,总和是7,满足条件。所以返回这两个索引,按升序排列是1和4。所以代码在这种情况下会正确返回。 那双重循环的顺序是否正确?比如当i=0的时候,数组元素是1,需要找是否有元素等于7-1=6。数组中的元素是2,3,-2,5,7。后面的元素有没有6?没有。所以i=0的时候没有找到。然后i=1的时候,找7-2=5,后面是否有5?是的,j=4的时候是5。所以这时候返回1和4。所以双重循环的顺序是正确的。 那这样的话,代码的大致结构应该是这样的: 读取n,数组,target。 然后循环i从0到n-1: 循环j从i+1到n-1: 如果array[i] + array[j] == target: 输出i和j,并返回。 这样就能保证找到的第一个符合条件的对是i最小的,并且j尽可能小。这样就能满足题目中的条件,即索引对中小的索引最小的那一组。例如,假设存在两个解,比如i=0,j=5和i=1,j=2。那么当i=0时,j=5会被先找到,所以返回0和5。而i=1的情况不会被遍历到,直到i=0的所有j都遍历完毕之后。所以这样的双重循环可以保证第一个找到的解是i最小的。 那这样的话,这样的算法是正确的。 那现在需要考虑如何实现这个逻辑。在C语言中,如何读取输入? 输入描述中的第一行是数组的长度,不超过100。第二行是数组元素。第三行是特定值。例如输入样例中的数组长度是6,数组是1 2 3 -2 5 7,特定值是7。输出是1 4。 所以C代码需要读取n,然后读取n个整数到数组,再读取target。然后进行双重循环。一旦找到,就输出i和j的顺序,按升序排列,即i和j已经满足i<j,所以直接输出i和j即可。 那具体的代码结构: #include <stdio.h> int main() { int n; scanf("%d", &n); int nums[100]; // 题目中说长度不超过100 for (int i = 0; i < n; ++i) { scanf("%d", &nums[i]); } int target; scanf("%d", &target); // 双重循环查找 for (int i = 0; i < n; ++i) { for (int j = i + 1; j < n; ++j) { if (nums[i] + nums[j] == target) { printf("%d %d\n", i, j); return 0; // 直接结束程序,找到第一个符合条件的 } } } // 根据题目描述,应该至少存在一个解?或者需要考虑无解的情况? // 题目描述中的例子存在解,但输入是否有解需要看具体情况。但题目可能保证有解? // 题目中的输出描述要求输出一行,假设总有一个解存在,否则可能需要处理。例如,假设题目保证存在解,所以无需处理。 // 但实际情况下可能需要考虑找不到的情况,比如输出什么?但题目可能不会给出这种情况的测试用例。所以这里可能不需要处理。 return 0; } 这样的代码应该能解决问题吗? 比如测试用例的情况。当数组是[1,2,3,-2,5,7],target是7时,双重循环的顺序: i=0,j从1到5: 检查1+2=3?不等于7。j=1:1+2=3。j=2:1+3=4。j=3:1+(-2)=-1。j=4:1+5=6。j=5:1+7=8。都不等于7。所以i=0没有找到。 i=1,j从2到5: i=1的元素是2。检查j=2(3)的总和5。不等于7。j=3是-2:2+(-2)=0。j=4是5:2+5=7,符合。所以i=1,j=4。输出1 4。程序结束。 那这样就正确了。 那这样的情况是正确的。 那如果存在多个解,比如比如数组中有多个符合条件的对,那么会返回第一个遇到的,也就是i最小的那个。例如数组[3,4,2,5],target是7。可能的解有i=0,j=1(3+4=7),i=1,j=3(4+3=7?假设数组是[3,4,2,5],那么i=0,j=1是3+4=7;i=2,j=3是2+5=7。那么在代码中,外层循环i=0的时候,j=1就找到了,所以会返回0和1。而不会到i=2的情况。所以符合题目条件。 所以这样的代码是正确的。 那这样,这个代码应该能符合题目要求。那这样应该就是正确的解法。</think>以下是解决该问题的C语言代码,按照题目要求找到两个总和为特定值的索引,并确保输出符合条件的最小索引对: ```c #include <stdio.h> int main() { int n; scanf("%d", &n); int nums[100]; for (int i = 0; i < n; ++i) { scanf("%d", &nums[i]); } int target; scanf("%d", &target); // 双重循环遍历所有可能的索引对 for (int i = 0; i < n; ++i) { for (int j = i + 1; j < n; ++j) { if (nums[i] + nums[j] == target) { printf("%d %d", i, j); return 0; // 找到第一个符合条件的对后立即结束 } } } return 0; } ``` ### 代码说明: 1. **输入处理**: - 读取数组长度 `n`。 - 读取数组元素到 `nums` 中。 - 读取目标值 `target`。 2. **双重循环遍历**: - 外层循环变量 `i` 从 `0` 到 `n-1`,表示第一个索引。 - 内层循环变量 `j` 从 `i+1` 到 `n-1`,表示第二个索引。 - 检查 `nums[i] + nums[j]` 是否等于 `target`,若满足则立即输出并结束程序。 3. **输出特性**: - 一旦找到符合条件的索引对,直接输出 `i` 和 `j`(由于 `i < j`,结果自然升序)。 - 双重循环的顺序保证了优先返回**小索引最小**的解(即遍历顺序是从左到右,优先找到更小的 `i`)。 ### 示例验证: 输入: ``` 6 1 2 3 -2 5 7 7 ``` 输出: ``` 1 4 ``` 代码通过双重循环找到 `nums[1] + nums[4] = 2 + 5 = 7`,符合要求。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值