leetcode刷题:每日一题:1128. 等价多米诺骨牌对的数量 and 牛客网刷题:两数之和 and 合并两个有序的数组

leetcode刷题:每日一题:1128. 等价多米诺骨牌对的数量 and 牛客网刷题:两数之和 and 合并两个有序的数组
参考思路:
注意点一:牌值为10以内的数组成,且两位数组成只为100以内的数,可用该两位数作为hash方法存储的地址,在数组中存储牌对数量。
注意点二:反转相等,则可自己制定规则,二维数据中,第一维始终小于第二维的数。
注意点三:如果牌对数为n,则能组成的排列数为Cn2

class Solution {
public:
    int numEquivDominoPairs(vector<vector<int>>& dominoes) {
        if (dominoes.empty())
            return 0;
        int num = dominoes.size();  
        vector<int> numbers(100);
        int result = 0;
        for( int i=0;i<num;i++)          //将所有的牌整理成小数在前 大数在后
        {
            int val;
            val = dominoes[i][0] < dominoes[i][1]?dominoes[i][0]*10+dominoes[i][1]:dominoes[i][1]*10+dominoes[i][0];
            result+= numbers[val];
            numbers[val]++;
        }
        
        return result;
    }
};

leetcode刷题:每日一题:1128. 等价多米诺骨牌对的数量 and 牛客网刷题:两数之和 and 合并两个有序的数组
leetcode刷题:每日一题:1128. 等价多米诺骨牌对的数量 and 牛客网刷题:两数之和 and 合并两个有序的数组
思路:普通思路就不多述说了,hash方法:将该数存在map容器中,将该数作为key值,遇到相同的数则存在value的vector数组中,查找复杂度为O(n),算法复杂度也为O(n)。

class Solution {
public:
    /**
     *
     * @param numbers int整型vector
     * @param target int整型
     * @return int整型vector
     */
    vector<int> twoSum(vector<int>& numbers, int target) {
        // write code here
        if (numbers.empty())
            return {};
        int index1,index2;
        int flag=0;
//         for (int i=0;i<numbers.size();i++)
//         {
//             if (numbers[i] > target )
//                 continue;
//             index1 = i;
//             for (int j=i+1;j<numbers.size();j++)
//             {
//                 if ( numbers[i]+numbers[j] == target )
//                 {
//                     index2 = j;
//                     flag = 1;
//                     break;
//                 }
//             }
//             if (flag == 1)
//                 break;
//         }
        //hash方法
        map<int, vector<int>> mapvalue;
        map<int, vector<int>>::iterator iter1,iter2;
        //存入hashtble
         for (int i=0;i<numbers.size();i++)
        {
             iter1 = mapvalue.find(numbers[i]);
             if ( iter1 == mapvalue.end())   //未找到该元素
             {
                 vector<int>indexs;
                 indexs.push_back(i);
                 mapvalue.insert(pair<int,vector<int>>(numbers[i],indexs));
             }
             else
                 iter1->second.push_back(i);
        }
        for (int i=0;i<numbers.size();i++)
        {
            if (numbers[i] > target )
                continue;
            iter1 = mapvalue.find(numbers[i]);
            if ( iter1 != mapvalue.end())
            {
                int next = target - iter1->first;
                index1 = iter1->second[0];
                iter2 = mapvalue.find(next);
                 
                if (iter2 != mapvalue.end() && ((iter1->second[0]!=iter2->second[0]) || (iter1->second[0]==iter2->second[0] && iter1->second.size()>1)) )
                {
                    if (iter2->first == iter1->first)
                        index2 = iter2->second[1];
                    else
                        index2 = iter2->second[0];
                    flag = 1;
                    break;
                }
            }
        }
         
         
        if (index1 < index2)
            return {index1+1,index2+1};
        else
            return {index2+1,index1+1};
    }
     
};

leetcode刷题:每日一题:1128. 等价多米诺骨牌对的数量 and 牛客网刷题:两数之和 and 合并两个有序的数组
思路:类似的题目均考虑逆序插入(尾插法),不用一一考虑是否需要后移,之后只需要比较大小,选择哪个数进行插入。

class Solution {
public:
    void merge(int A[], int m, int B[], int n) {
        int index1=m-1,index2=n-1;
        int end = m+n-1;
        while ( index1>=0 && index2>=0)
        {
            A[end--] = A[index1]>B[index2]?A[index1--]:B[index2--];
        }
        while (index1>=0)
            A[end--] = A[index1--];
        while (index2>=0)
            A[end--] = B[index2--];
         
    }
};

其中,while(index1>=0)这段其实可以不写,因为此时index1=end。

上一篇:babel转义es6---简单的写,更好的用


下一篇:C++中map的用法