列表

详情


1538. 找出隐藏数组中出现次数最多的元素

给定一个整数数组 nums,且 nums 中的所有整数都为 01。你不能直接访问这个数组,你需要使用 API ArrayReader ,该 API 含有下列成员函数:

你可以调用 query() 最多 2 * n 次,其中 n 等于 ArrayReader.length()

返回 nums 中出现次数最多的值的任意索引,若所有的值出现次数均相同,返回 -1。

 

示例 1:

输入: nums = [0,0,1,0,1,1,1,1]
输出: 5
解释: API 的调用情况如下:
reader.length() // 返回 8,因为隐藏数组中有 8 个元素。
reader.query(0,1,2,3) // 返回 2,查询元素 nums[0], nums[1], nums[2], nums[3] 间的比较。
// 三个元素等于 0 且一个元素等于 1 或出现相反情况。
reader.query(4,5,6,7) // 返回 4,因为 nums[4], nums[5], nums[6], nums[7] 有相同值。
我们可以推断,最常出现的值在最后 4 个元素中。
索引 2, 4, 6, 7 也是正确答案。

示例 2:

输入: nums = [0,0,1,1,0]
输出: 0

示例 3:

输入: nums = [1,0,1,0,1,0,1,0]
输出: -1

 

提示:

 

进阶:要找到出现次数最多的元素,需要至少调用 query() 多少次?

原站题解

去查看

上次编辑到这里,代码来自缓存 点击恢复默认模板
/** * // This is the ArrayReader's API interface. * // You should not implement it, or speculate about its implementation * class ArrayReader { * public: * // Compares 4 different elements in the array * // return 4 if the values of the 4 elements are the same (0 or 1). * // return 2 if three elements have a value equal to 0 and one element has value equal to 1 or vice versa. * // return 0 : if two element have a value equal to 0 and two elements have a value equal to 1. * int query(int a, int b, int c, int d); * * // Returns the length of the array * int length(); * }; */ class Solution { public: int guessMajority(ArrayReader &reader) { } };

python3 解法, 执行用时: 136 ms, 内存消耗: 20.2 MB, 提交时间: 2023-10-22 10:31:05

# """
# This is the ArrayReader's API interface.
# You should not implement it, or speculate about its implementation
# """
#class ArrayReader(object):
#	 # Compares 4 different elements in the array
#	 # return 4 if the values of the 4 elements are the same (0 or 1).
#	 # return 2 if three elements have a value equal to 0 and one element has value equal to 1 or vice versa.
#	 # return 0 : if two element have a value equal to 0 and two elements have a value equal to 1.
#    def query(self, a: int, b: int, c: int, d: int) -> int:
#
#	 # Returns the length of the array
#    def length(self) -> int:
#
class Solution:
    def guessMajority(self, reader: 'ArrayReader') -> int:
        length = reader.length()
        equalTo0 = [0]
        unequalTo0 = []
        case1 = reader.query(0, 1, 2, 3)
        case2 = reader.query(1, 2, 3, 4)
        case3 = reader.query(0, 2, 3, 4)
        case4 = reader.query(0, 1, 3, 4)
        case5 = reader.query(0, 1, 2, 4)

        if case2 == case3:
            # i0 == i1      
            equalTo0.append(1)
        else:
            # i0 != i1
            unequalTo0.append(1)

        if case2 == case4:
            # i0 == i2
            equalTo0.append(2)
        else:
            # !0 != i2
            unequalTo0.append(2)

        if case2 == case5:
            # i0 == i3
            equalTo0.append(3)
        else:
            # !0 != i3
            unequalTo0.append(3)

        for i in range(4, length):
            case = reader.query(1, 2, 3, i)
            if case1 == case:
                equalTo0.append(i)
            else:
                unequalTo0.append(i)

        # print(equalTo0)
        # print(unequalTo0)
        if len(equalTo0) == len(unequalTo0):
            return -1
        elif len(equalTo0) > len(unequalTo0):
            return equalTo0[0]
        else:
            return unequalTo0[0]

rust 解法, 执行用时: 24 ms, 内存消耗: 2.6 MB, 提交时间: 2023-10-22 10:30:23

/**
 * // This is the ArrayReader's API interface.
 * // You should not implement it, or speculate about its implementation
 * struct ArrayReader;
 * impl ArrayReader {
 *     // Compares 4 different elements in the array
 *     // return 4 if the values of the 4 elements are the same (0 or 1).
 *     // return 2 if three elements have a value equal to 0 and one element has value equal to 1 or vice versa.
 *     // return 0 : if two element have a value equal to 0 and two elements have a value equal to 1.
 *     pub fn query(a: i32, b: i32, c: i32, d: i32) -> i32 {}
 *
 *     // Returns the length of the array
 *     pub fn length() -> i32 {}
 * };
 */
impl Solution {
    pub fn get_majority(reader: &ArrayReader) -> i32 {
        let n = reader.length() as usize;
        let mut z = 1;
        let mut o = 0;

        for i in 1..n {
            let mut other = vec![];

            for j in 1..n {
                if j != i {
                    other.push(j);
                }
                if other.len() == 3 {
                    break;
                }
            }

            let mut q1 = vec![0];
            let mut q2 = vec![i as i32];

            for j in other {
                q1.push(j as i32);
                q2.push(j as i32);
            }

            q2.sort();

            if reader.query(q1[0], q1[1], q1[2], q1[3]) != reader.query(q2[0], q2[1], q2[2], q2[3]) {
                o += 1;
            } else {
                z += 1;
            }

            if o > n / 2 || z > n / 2 {
                return i as i32;
            }
        }

        -1
    }
}

java 解法, 执行用时: 5 ms, 内存消耗: 47.9 MB, 提交时间: 2023-10-22 10:29:26

/**
 * // This is the ArrayReader's API interface.
 * // You should not implement it, or speculate about its implementation
 * interface ArrayReader {
 *   public:
 *     // Compares 4 different elements in the array
 *     // return 4 if the values of the 4 elements are the same (0 or 1).
 *     // return 2 if three elements have a value equal to 0 and one element has value equal to 1 or vice versa.
 *     // return 0 : if two element have a value equal to 0 and two elements have a value equal to 1.
 *     public int query(int a, int b, int c, int d);
 *
 *     // Returns the length of the array
 *     public int length();
 * };
 */

class Solution {
    public int guessMajority(ArrayReader reader) {
        
        int n=reader.length();

        int start=reader.query(0,1,2,3);

        int i1=3;int i2=-1;
        int group1=1,group2=0;

        //假设 index3 是group1      

        for(int i=4;i<n;i++){
            int q=reader.query(0,1,2,i);
            if(q==start)group1++;
            else {
                i2=i;
                group2++;
            }
        }

        //再看前面3个值

        int sudo=reader.query(0,1,2,4);
        //test 0
        if(reader.query(1,2,3,4)==sudo){
            group1++;
        }else{
            group2++;
            i2=0;
        }

        //test 2
        if(reader.query(0,1,3,4)==sudo){
            group1++;
        }else{
           group2++;i2=2;
        }

        //test1
        if(reader.query(0,2,3,4)==sudo){
            group1++;
        }else{
            group2++;i2=1;
        }

        if(group1==group2)return -1;
        if(group1>group2)return i1;
        return i2;

    }
}

cpp 解法, 执行用时: 124 ms, 内存消耗: 31.1 MB, 提交时间: 2023-10-22 10:28:24

/**
 * // This is the ArrayReader's API interface.
 * // You should not implement it, or speculate about its implementation
 * class ArrayReader {
 *   public:
 *     // Compares 4 different elements in the array
 *     // return 4 if the values of the 4 elements are the same (0 or 1).
 *     // return 2 if three elements have a value equal to 0 and one element has value equal to 1 or vice versa.
 *     // return 0 : if two element have a value equal to 0 and two elements have a value equal to 1.
 *     int query(int a, int b, int c, int d);
 *
 *     // Returns the length of the array
 *     int length();
 * };
 */
class Solution {
public:
    int guessMajority(ArrayReader &reader) {
        int n = reader.length();
        vector<int> v(n);
        v[0] = 1;

        auto find = [&](int num) {
            int idx = -1;
            for (int i = 0; i < n; ++i) {
                if (v[i] == num) {
                    idx = i;
                    break;
                }
            }
            return idx;
        };

        int q0123 = reader.query(0, 1, 2, 3);
        int q0124 = reader.query(0, 1, 2, 4);
        int q0134 = reader.query(0, 1, 3, 4);
        int q0234 = reader.query(0, 2, 3, 4);
        int q1234 = reader.query(1, 2, 3, 4);
        v[1] = (q0234 == q1234);
        v[2] = (q0134 == q1234);
        v[3] = (q0124 == q1234);
        v[4] = (q0123 == q1234);

        int prev = q1234;
        for (int i = 5; i < n; ++i) {
            int curr = reader.query(i - 3, i - 2, i - 1, i);
            v[i] = (prev == curr ? v[i - 4] : 1 - v[i - 4]);
            prev = curr;
        }

        int sum = accumulate(v.begin(), v.end(), 0);
        if (sum * 2 == n) {
            return -1;
        }
        return sum * 2 < n ? find(0) : find(1);
    }
};

cpp 解法, 执行用时: 412 ms, 内存消耗: 89.3 MB, 提交时间: 2023-10-22 10:27:53

/**
 * // This is the ArrayReader's API interface.
 * // You should not implement it, or speculate about its implementation
 * class ArrayReader {
 *   public:
 *     // Compares 4 different elements in the array
 *     // return 4 if the values of the 4 elements are the same (0 or 1).
 *     // return 2 if three elements have a value equal to 0 and one element has value equal to 1 or vice versa.
 *     // return 0 : if two element have a value equal to 0 and two elements have a value equal to 1.
 *     int query(int a, int b, int c, int d);
 *
 *     // Returns the length of the array
 *     int length();
 * };
 */

class Solution {
public:
    int guessMajority(ArrayReader &reader) {
        int n = reader.length();
        vector<int> v(n);
        v[0] = 1;

        auto checkIfSame = [&](int p, int q) {
            vector<int> chooseP = {p};
            vector<int> chooseQ = {q};
            for (int i = 0; i < n; ++i) {
                if (i != p && i != q) {
                    chooseP.push_back(i);
                    chooseQ.push_back(i);
                    if (chooseP.size() == 4) {
                        break;
                    }
                }
            }
            sort(chooseP.begin(), chooseP.end());
            sort(chooseQ.begin(), chooseQ.end());
            return reader.query(chooseP[0], chooseP[1], chooseP[2], chooseP[3]) == \
                   reader.query(chooseQ[0], chooseQ[1], chooseQ[2], chooseQ[3]);
        };

        auto find = [&](int num) {
            int idx = -1;
            for (int i = 0; i < n; ++i) {
                if (v[i] == num) {
                    idx = i;
                    break;
                }
            }
            return idx;
        };

        for (int i = 1; i < n; ++i) {
            v[i] = checkIfSame(0, i);
        }
        
        int sum = accumulate(v.begin(), v.end(), 0);
        if (sum * 2 == n) {
            return -1;
        }
        return sum * 2 < n ? find(0) : find(1);
    }
};

上一题