信息同步模拟

93 阅读5分钟

信息同步模拟

背景介绍

在一个网络管理系统中,数据库中维护着一张实时更新的当前网元信息表 (curTable) 。为了保证数据的准确性和完整性,系统需要定期从一个备份信息表 (bakTable) 中同步数据。你的任务是实现这个同步逻辑。

核心实体

  1. 当前网元信息 (curTable):

    • 这是一个记录列表,每个记录包含三个字段:[neId, neName, neFlag]
    • neId 是网元的唯一标识符(主键)。
  2. 备份网元信息 (bakTable):

    • 这是一个作为数据源的记录列表,每个记录包含两个字段:[neId, neName]

同步规则

同步过程以 bakTable 为基准,遍历其中的每一条记录,并更新 curTable。具体规则如下:

  • 对于 bakTable 中的一条记录 [id_b, name_b]:

    • curTable 中查找是否有 neIdid_b 相同的记录。

      • 情况一:如果找到了 (neId 已存在) -> 更新操作

        • bakTable 中的 neName (name_b) 覆盖 curTable 中对应记录的 neName
        • neFlag 字段保持不变
      • 情况二:如果没找到 (neId 不存在) -> 新增操作

        • curTable 中新增一条记录。
        • 新记录的 neIdneName 来自 bakTable
        • 新记录的 neFlag 初始值设为 0
  • 对于 curTable 中存在、但 bakTable 中不存在的记录:

    • 这些记录不受本次同步影响,保持原样

输出要求

  • 返回经过同步操作后的、完整的当前网元信息表 (curTable)
  • 最终返回的列表必须按照 neId 升序排列。

解答要求

  • 时间限制: 1000ms
  • 内存限制: 256MB

输入格式

  1. 第一个参数 curTable:

    • 一个二维数组/列表。
    • 0 <= curTable.length <= 50000
  2. 第二个参数 bakTable:

    • 一个二维数组/列表。
    • 0 <= bakTable.length <= 50000
  • curTable.lengthbakTable.length 不同时为 0。
  • 1 <= neId <= 100000
  • neName 仅由字母和数字组成,长度范围 [1, 20]
  • 0 <= neFlag <= 9

输出格式

  • 一个二维数组/列表,表示排序后的、最终的 curTable 内容。

样例

输入样例 1

// curTable
[[256, "NE256", 1], [290, "NE290", 0], [268, "26800000", 1], [257, "NE257", 1]]
// bakTable
[[273, "NE273"], [268, "NE268"], [257, "NE257"]]

输出样例 1

[[256, "NE256", 1], [257, "NE257", 1], [268, "NE268", 1], [273, "NE273", 0], [290, "NE290", 0]]

样例 1 执行流程详解

  1. 初始状态:

    • curTable 中有 neId: {256, 290, 268, 257}
    • bakTable 中有 neId: {273, 268, 257}
  2. 处理 bakTable -> [273, "NE273"]:

    • neId = 273curTable 中不存在。
    • 操作: 新增。
    • curTable 中加入 [273, "NE273", 0]
  3. 处理 bakTable -> [268, "NE268"]:

    • neId = 268curTable 中存在,其记录为 [268, "26800000", 1]
    • 操作: 更新。
    • curTable 中的记录变为 [268, "NE268", 1] (只更新了 neName)。
  4. 处理 bakTable -> [257, "NE257"]:

    • neId = 257curTable 中存在,其记录为 [257, "NE257", 1]
    • 操作: 更新。
    • curTable 中的记录变为 [257, "NE257", 1] (虽然 neName 没变,但仍执行更新逻辑)。
  5. 同步后 curTable 状态 (未排序):

    [[256, "NE256", 1], [290, "NE290", 0], [268, "NE268", 1], [257, "NE257", 1], [273, "NE273", 0]]

  6. 最终输出 (按 neId 升序排序后):

    [[256, "NE256", 1], [257, "NE257", 1], [268, "NE268", 1], [273, "NE273", 0], [290, "NE290", 0]]

import java.util.*;

/**
 * 模拟一个网元信息同步系统.
 * 核心功能是根据备份表(bakTable)来更新当前表(curTable)。
 */
public class NeSyncSystem {

    /**
     * 主方法,执行同步逻辑.
     * @param curTable 当前网元信息表,格式为 [[neId, neName, neFlag], ...]
     * @param bakTable 备份的网元信息表,格式为 [[neId, neName], ...]
     * @return 同步后并按 neId 升序排列的网元信息列表
     */
    public List<List<Object>> sync(Object[][] curTable, Object[][] bakTable) {
        
        // --- 步骤 1: 将 curTable 加载到一个 TreeMap 中 ---
        // 选择 TreeMap 的原因:
        // 1. 它是一个 Map,可以通过 neId (key) 实现 O(logN) 复杂度的快速查找、更新和插入。
        // 2. 它能自动根据 key (neId) 对所有条目进行升序排序,这使得最后输出时无需再手动排序。
        // Map 的 Key 是 neId (Integer),Value 是一个包含 neName 和 neFlag 的对象数组。
        Map<Integer, Object[]> syncedMap = new TreeMap<>();

        for (Object[] row : curTable) {
            int neId = (Integer) row[0];
            String neName = (String) row[1];
            int neFlag = (Integer) row[2];
            // 将 neName 和 neFlag 存入值数组
            syncedMap.put(neId, new Object[]{neName, neFlag});
        }

        // --- 步骤 2: 遍历 bakTable,根据同步规则更新 TreeMap ---
        for (Object[] bakRow : bakTable) {
            int bakNeId = (Integer) bakRow[0];
            String bakNeName = (String) bakRow[1];

            // 检查 bakNeId 是否已存在于当前的表中
            if (syncedMap.containsKey(bakNeId)) {
                // --- 更新规则 ---
                // 如果存在,则更新 neName 的值,neFlag 保持不变。
                Object[] curRecord = syncedMap.get(bakNeId);
                curRecord[0] = bakNeName; // 更新 neName
            } else {
                // --- 新增规则 ---
                // 如果不存在,则新增一条记录,neFlag 初始设置为 0。
                syncedMap.put(bakNeId, new Object[]{bakNeName, 0});
            }
        }

        // --- 步骤 3: 将 TreeMap 转换为题目要求的输出格式 ---
        List<List<Object>> resultList = new ArrayList<>();
        
        // 遍历 TreeMap。由于 TreeMap 的特性,这里的遍历顺序已经是按 neId 升序的。
        for (Map.Entry<Integer, Object[]> entry : syncedMap.entrySet()) {
            List<Object> resultRow = new ArrayList<>();
            
            // 依次添加 neId, neName, neFlag
            resultRow.add(entry.getKey());                 // neId (来自 Map 的 key)
            resultRow.add(entry.getValue()[0]);            // neName (来自 Map value 数组的第一个元素)
            resultRow.add(entry.getValue()[1]);            // neFlag (来自 Map value 数组的第二个元素)
            
            resultList.add(resultRow);
        }

        return resultList;
    }
}