前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >2024 前六周数据出炉:进击的华为

2024 前六周数据出炉:进击的华为

作者头像
宫水三叶的刷题日记
发布2024-03-13 15:35:25
810
发布2024-03-13 15:35:25
举报

转移的份额

据机构数据显示,今年前六周,苹果公司在中国的 iPhone 销量同比下降 24%,而华为手机销量增加 64%。

华为手机销量主要受 Mate60 影响,可见随着华为的芯片危机逐步缓解,华为会持续侵蚀以苹果为首的高端机器的市场份额。

与去年相比,今年前六周,华为市场份额从 9.4% 增加至 16.5% ,而苹果份额从 19% 下滑至 15.7%。

这还真就是网友喊的:遥遥领先 ?

...

回归主线。

之前分享过两次「华为 OD」的算法原题,有读者反馈说有点难。

题目变难,其实还是一个候选人供过于求的问题。

这次分享一道难度稍稍合理的「华为 OD」的算法原题。

题目描述

平台:LeetCode

题号:1743

存在一个由 n 个不同元素组成的整数数组 nums ,但你已经记不清具体内容,好在你还记得 nums 中的每一对相邻元素。

给你一个二维整数数组 adjacentPairs ,大小为 n - 1 ,其中每个

adjacentPairs[i] = [u_i, v_i]

表示元素

u_i

v_i

nums 中相邻。

题目数据保证所有由元素 nums[i]nums[i+1] 组成的相邻元素对都存在于 adjacentPairs 中,存在形式可能是 [nums[i], nums[i+1]] ,也可能是 [nums[i+1], nums[i]] 。这些相邻元素对可以「按任意顺序」出现。

返回原始数组 nums 。如果存在多种解答,返回其中任意一个即可。

示例 1:

代码语言:javascript
复制
输入:adjacentPairs = [[2,1],[3,4],[3,2]]

输出:[1,2,3,4]

解释:数组的所有相邻元素对都在 adjacentPairs 中。
特别要注意的是,adjacentPairs[i] 只表示两个元素相邻,并不保证其 左-右 顺序。

示例 2:

代码语言:javascript
复制
输入:adjacentPairs = [[4,-2],[1,4],[-3,1]]

输出:[-2,4,1,-3]

解释:数组中可能存在负数。
另一种解答是 [-3,1,4,-2] ,也会被视作正确答案。

示例 3:

代码语言:javascript
复制
输入:adjacentPairs = [[100000,-100000]]

输出:[100000,-100000]

提示:

nums.length == n
adjacentPairs.length == n - 1
adjacentPairs[i].length == 2
2 <= n <= 10^5
-10^5 <= nums[i], u_i, v_i <= 10^5
  • 题目数据保证存在一些以 adjacentPairs 作为元素对的数组

单向构造(哈希表计数)

根据题意,由于所有的相邻关系都会出现在

nums

中,假设其中一个合法数组为

ans

,长度为

n

那么显然

ans[0]

ans[n - 1]

nums

中只存在一对相邻关系,而其他

ans[i]

则存在两对相邻关系。

因此我们可以使用「哈希表」对

nums

中出现的数值进行计数,找到“出现一次”的数值作为

ans

数值的首位,然后根据给定的相邻关系进行「单向构造」,为了方便找到某个数其相邻的数是哪些,我们还需要再开一个「哈希表」记录相邻关系。

Java 代码:

代码语言:javascript
复制
class Solution {
    public int[] restoreArray(int[][] adjacentPairs) {
        int m = adjacentPairs.length, n = m + 1;
        Map<Integer, Integer> cnts = new HashMap<>();
        Map<Integer, List<Integer>> map = new HashMap<>();
        for (int[] ap : adjacentPairs) {
            int a = ap[0], b = ap[1];
            cnts.put(a, cnts.getOrDefault(a, 0) + 1);
            cnts.put(b, cnts.getOrDefault(b, 0) + 1);
            List<Integer> alist = map.getOrDefault(a, new ArrayList<>());
            alist.add(b);
            map.put(a, alist);
            List<Integer> blist = map.getOrDefault(b, new ArrayList<>());
            blist.add(a);
            map.put(b, blist);
        }
        int start = -1;
        for (int i : cnts.keySet()) {
            if (cnts.get(i) == 1) {
                start = i;
                break;
            }
        }
        int[] ans = new int[n];
        ans[0] = start;
        ans[1] = map.get(start).get(0);
        for (int i = 2; i < n; i++) {
            int x = ans[i - 1];
            List<Integer> list = map.get(x);
            for (int j : list) {
                if (j != ans[i - 2]) ans[i] = j;
            }
        }
        return ans;
    }
}

C++ 代码:

代码语言:javascript
复制
class Solution {
public:
    vector<int> restoreArray(vector<vector<int>>& adjacentPairs) {
        unordered_map<int, int> cnts;
        unordered_map<int, vector<int>> map;
        for(auto& pair : adjacentPairs){
            int a = pair[0], b = pair[1];
            cnts[a]++, cnts[b]++;
            map[a].push_back(b);
            map[b].push_back(a);
        }
        int start;
        for(auto& i : cnts) {
            if(i.second == 1){
                start = i.first;
                break;
            }
        }
        int n = adjacentPairs.size() + 1;
        vector<int> ans(n);
        ans[0] = start;
        ans[1] = map[start][0];
        for(int i = 2; i < n; i++){
            int x = ans[i - 1];
            for(int j : map[x])
                if(j != ans[i-2]) ans[i] = j;
        }
        return ans;
    }
};

Python 代码:

代码语言:javascript
复制
class Solution:
    def restoreArray(self, adjacentPairs: List[List[int]]) -> List[int]:
        cnts = defaultdict(int)
        map = defaultdict(list)
        for ap in adjacentPairs:
            a, b = ap[0], ap[1]
            cnts[a] += 1 
            cnts[b] += 1
            map[a].append(b)
            map[b].append(a)
        start = next(i for i in cnts if cnts[i] == 1)
        n = len(adjacentPairs) + 1
        ans = [0] * n
        ans[0] = start
        ans[1] = map[start][0]
        for i in range(2, n):
            x = ans[i - 1]
            for j in map[x]:
                if j != ans[i - 2]: 
                    ans[i] = j
        return ans

TypeScript 代码:

代码语言:javascript
复制
function restoreArray(adjacentPairs: number[][]): number[] {
    const cnts: {[key: number]: number} = {};
    const map: {[key: number]: number[]} = {};
    for(let pair of adjacentPairs){
        let a: number = pair[0], b: number = pair[1];
        cnts[a] = !cnts[a] ? 1 : cnts[a] + 1;
        cnts[b] = !cnts[b] ? 1 : cnts[b] + 1;
        if(!map[a]) map[a] = [];
        if(!map[b]) map[b] = [];
        map[a].push(b);
        map[b].push(a);
    }
    let start: number;
    for(let key in cnts){
        if(cnts[key] == 1){
            start = Number(key);
            break;
        }
    }
    const n: number = adjacentPairs.length + 1;
    const ans: number[] = Array(n).fill(0);
    ans[0] = start;
    ans[1] = map[start][0];
    for(let i = 2; i<n; i++){
        let x: number = ans[i-1];
        for(let j of map[x]){
            if(j !== ans[i-2]) ans[i] = j;
        }
    }
    return ans;
};
  • 时间复杂度:
O(n)
  • 空间复杂度:
O(n)

双向构造(双指针)

在解法一中,我们通过「哈希表」计数得到

ans

首位元素作为起点,进行「单向构造」。

那么是否存在使用任意数值作为起点进行的双向构造呢?

答案是显然的,我们可以利用

ans

的长度为

2 <= n <= 10^5

,构造一个长度

10^6

的数组

q

(这里可以使用 static 进行加速,让多个测试用例共享一个大数组)。

?这里

q

数组不一定要开成

1e6

大小,只要我们

q

大小大于

ans

的两倍,就不会存在越界问题。 ?

q

数组的 「中间位置」 开始,先随便将其中一个元素添加到中间位置,使用「双指针」分别往「两边拓展」(lr 分别指向左右待插入的位置)。

l 指针和 r 指针之间已经有

n

个数值,说明整个

ans

构造完成,我们将

[l + 1, r - 1]

范围内的数值输出作为答案即可。

Java 代码:

代码语言:javascript
复制
class Solution {
    static int N = (int)1e6+10;
    static int[] q = new int[N];
    public int[] restoreArray(int[][] adjacentPairs) {
        int m = adjacentPairs.length, n = m + 1;
        Map<Integer, List<Integer>> map = new HashMap<>();
        for (int[] ap : adjacentPairs) {
            int a = ap[0], b = ap[1];
            List<Integer> alist =  map.getOrDefault(a, new ArrayList<>());
            alist.add(b);
            map.put(a, alist);
            List<Integer> blist = map.getOrDefault(b, new ArrayList<>());
            blist.add(a);
            map.put(b, blist);
        }
        int l = N / 2, r = l + 1;
        int std = adjacentPairs[0][0];
        List<Integer> list = map.get(std);
        q[l--] = std;
        q[r++] = list.get(0);
        if (list.size() > 1) q[l--] = list.get(1);
        while ((r - 1) - (l + 1) + 1 < n) {
            List<Integer> alist = map.get(q[l + 1]);
            int j = l;
            for (int i : alist) {
                if (i != q[l + 2]) q[j--] = i;
            }
            l = j;

            List<Integer> blist = map.get(q[r - 1]);
            j = r;
            for (int i : blist) {
                if (i != q[r - 2]) q[j++] = i;
            }
            r = j;
        }
        int[] ans = new int[n];
        for (int i = l + 1, idx = 0; idx < n; i++, idx++) {
            ans[idx] = q[i];
        }
        return ans;
    }
}

C++ 代码:

代码语言:javascript
复制
#define N 1000010
class Solution {
public:
    vector<int> restoreArray(vector<vector<int>>& adjacentPairs) {
        int m = adjacentPairs.size(), n = m + 1;
        unordered_map<int, vector<int>> map;
        for(auto& pair : adjacentPairs){
            int a = pair[0], b = pair[1];
            map[a].push_back(b);
            map[b].push_back(a);
        }
        int l = N / 2, r = l + 1;
        int s = adjacentPairs[0][0];
        vector<int> q(N, 0);
        q[l--] = s;
        q[r++] = map[s][0];
        if (map[s].size() > 1) q[l--] = map[s][1];
        while ((r - 1) - (l + 1) + 1 < n){
            vector<int> list = map[q[l + 1]];
            int j = l;
            for(auto& i : list){
                if(i != q[l + 2]) q[j--] = i;
            }
            l = j;

            list = map[q[r - 1]];
            j = r;
            for(auto& i : list){
                if(i != q[r - 2]) q[j++] = i;
            }
            r = j;
        }
        vector<int> ans(n);
        for(int i = l + 1, idx = 0; idx < n; ++i, ++idx){
            ans[idx] = q[i];
        }
        return ans;
    }
};
  • 时间复杂度:
O(n)
  • 空间复杂度:
O(n)

我是宫水三叶,每天都会分享算法知识,并和大家聊聊近期的所见所闻。

本文参与?腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2024-03-06,如有侵权请联系?cloudcommunity@tencent.com 删除

本文分享自 宫水三叶的刷题日记 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与?腾讯云自媒体分享计划? ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 转移的份额
  • 题目描述
  • 单向构造(哈希表计数)
  • 双向构造(双指针)
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
http://www.vxiaotou.com