diff --git a/.eslintrc.js b/.eslintrc.js index 991aab5..2be3590 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -1,80 +1,82 @@ module.exports = { - 'env': { - 'browser': true, - 'es2020': true, - 'node': true - }, - 'extends': [ - 'eslint:recommended', - 'plugin:@typescript-eslint/recommended' - ], - 'parser': '@typescript-eslint/parser', - 'parserOptions': { - 'ecmaVersion': 6, - 'sourceType': 'module' - // 'project': './tsconfig.json', - }, - 'plugins': [ - '@typescript-eslint' - ], + env: { + browser: true, + es2020: true, + node: true, + }, + extends: ["eslint:recommended", "plugin:@typescript-eslint/recommended"], + parser: "@typescript-eslint/parser", + parserOptions: { + ecmaVersion: 6, + sourceType: "module", + // 'project': './tsconfig.json', + }, + plugins: ["@typescript-eslint"], + /** + * 规则写法 + * 1、'quotes': 0; -- 0关闭,1警告,2错误 + * 2、'quotes': 'off'; -- off关闭,warn警告,error错误 + * 3、'quotes': ['error', 'single']; 'error'是提示类型,'single'是参数。参数不止一个的时候写成{} + */ + rules: { + // 是否检查变量已申明但未使用:警告。 + "@typescript-eslint/no-unused-vars": ["warn"], + // 强制单引号:开启,自动修正 + quotes: 0, + // 强制分号:js 关闭,ts 强制分号。 + semi: ["off"], + // 'semi': ['off'], + // 定义变量时自动类型推断:关闭 + "@typescript-eslint/no-inferrable-types": ["off"], + // 强制const:关闭 + "prefer-const": ["off"], + // 不允许空函数:关闭 + "@typescript-eslint/no-empty-function": ["off"], + // 禁止特定类型:关闭。 PS:如果打开 Function 类型会报错 + "@typescript-eslint/ban-types": ["off"], + // 禁止多余的分号:关闭。 PS:打开后,某些大括号结束加分号会报错 + "@typescript-eslint/no-extra-semi": ["off"], + // 检查函数是否有返回值:警告。 PS:有些老代码没有返回值,历史包袱重,暂时不强制报错 + "@typescript-eslint/explicit-module-boundary-types": ["warn"], + // 禁止给变量赋值为 this:关闭。 + "@typescript-eslint/no-this-alias": ["off"], + // 禁止使用 requires:关闭。 + "@typescript-eslint/no-var-requires": ["off"], + // 检测无法访问的代码:关闭。 PS:有时候需要用 return 注释掉后面的代码 + "no-unreachable": ["off"], /** - * 规则写法 - * 1、'quotes': 0; -- 0关闭,1警告,2错误 - * 2、'quotes': 'off'; -- off关闭,warn警告,error错误 - * 3、'quotes': ['error', 'single']; 'error'是提示类型,'single'是参数。参数不止一个的时候写成{} + * 是否可以直接调用对象方法:关闭。 + * PS:暂时关闭。目前写法:myObject.hasOwnProperty('name') ,推荐写法:Object.prototype.hasOwnProperty.call(foo, "bar") */ - 'rules': { - // 是否检查变量已申明但未使用:警告。 - '@typescript-eslint/no-unused-vars': ['warn'], - // 强制单引号:开启,自动修正 - 'quotes': 0, - // 强制分号:js 关闭,ts 强制分号。 - 'semi': ['off'], - // 'semi': ['off'], - // 定义变量时自动类型推断:关闭 - '@typescript-eslint/no-inferrable-types': ['off'], - // 强制const:关闭 - 'prefer-const': ['off'], - // 不允许空函数:关闭 - '@typescript-eslint/no-empty-function': ['off'], - // 禁止特定类型:关闭。 PS:如果打开 Function 类型会报错 - '@typescript-eslint/ban-types': ['off'], - // 禁止多余的分号:关闭。 PS:打开后,某些大括号结束加分号会报错 - '@typescript-eslint/no-extra-semi': ['off'], - // 检查函数是否有返回值:警告。 PS:有些老代码没有返回值,历史包袱重,暂时不强制报错 - '@typescript-eslint/explicit-module-boundary-types': ['warn'], - // 禁止给变量赋值为 this:关闭。 - '@typescript-eslint/no-this-alias': ['off'], - // 禁止使用 requires:关闭。 - '@typescript-eslint/no-var-requires': ['off'], - // 检测无法访问的代码:关闭。 PS:有时候需要用 return 注释掉后面的代码 - 'no-unreachable': ['off'], - /** - * 是否可以直接调用对象方法:关闭。 - * PS:暂时关闭。目前写法:myObject.hasOwnProperty('name') ,推荐写法:Object.prototype.hasOwnProperty.call(foo, "bar") - */ - 'no-prototype-builtins': ['off'], - // 是否允许函数内定义函数:关闭。 - 'no-inner-declarations': ['off'], - // 不允许判断条件写死:关闭。 PS:打开后,if(false){} 这种判断语句会报错 - 'no-constant-condition': ['off'], - // get 和 set 是否必须放在一起:关闭。 - '@typescript-eslint/adjacent-overload-signatures': ['off'], - "no-async-promise-executor": ['off'] + "no-prototype-builtins": ["off"], + // 是否允许函数内定义函数:关闭。 + "no-inner-declarations": ["off"], + // 不允许判断条件写死:关闭。 PS:打开后,if(false){} 这种判断语句会报错 + "no-constant-condition": ["off"], + // get 和 set 是否必须放在一起:关闭。 + "@typescript-eslint/adjacent-overload-signatures": ["off"], + "no-async-promise-executor": ["off"], + "prefer-spread": ["off"], + "prefer-rest-params": ["off"], + "@typescript-eslint/no-explicit-any": ["off"], + // "function-paren-newline": ["off", { minItems: 5 }], + "max-len": ["warn", { code: 120 }], + }, + // 如果有 js 和 ts 需要分开指定的规则,就 js 写 rules 里,ts 写 overrides 里 + overrides: [ + { + // enable the rule specifically for TypeScript files + files: ["*.ts", "*.tsx"], + rules: { + // 强制分号:开启,自动修正 + semi: ["error", "always"], + // '@typescript-eslint/explicit-module-boundary-types': ['error'] + }, }, - // 如果有 js 和 ts 需要分开指定的规则,就 js 写 rules 里,ts 写 overrides 里 - 'overrides': [{ - // enable the rule specifically for TypeScript files - 'files': ['*.ts', '*.tsx'], - 'rules': { - // 强制分号:开启,自动修正 - 'semi': ['error', 'always'], - // '@typescript-eslint/explicit-module-boundary-types': ['error'] - } - }], - // 定义全局变量 - 'globals': { - 'Global': true - } + ], + // 定义全局变量 + globals: { + Global: true, + }, }; diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 823729f..9dba4aa 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -13,9 +13,7 @@ name: "CodeQL" on: push: - branches: [ "main" ] - schedule: - - cron: '45 21 * * 2' + branches: ["release"] jobs: analyze: @@ -29,43 +27,42 @@ jobs: strategy: fail-fast: false matrix: - language: [ 'javascript' ] + language: ["javascript"] # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ] # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support steps: - - name: Checkout repository - uses: actions/checkout@v3 + - name: Checkout repository + uses: actions/checkout@v3 - # Initializes the CodeQL tools for scanning. - - name: Initialize CodeQL - uses: github/codeql-action/init@v2 - with: - languages: ${{ matrix.language }} - # If you wish to specify custom queries, you can do so here or in a config file. - # By default, queries listed here will override any specified in a config file. - # Prefix the list here with "+" to use these queries and those in the config file. - - # Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs - # queries: security-extended,security-and-quality + # Initializes the CodeQL tools for scanning. + - name: Initialize CodeQL + uses: github/codeql-action/init@v2 + with: + languages: ${{ matrix.language }} + # If you wish to specify custom queries, you can do so here or in a config file. + # By default, queries listed here will override any specified in a config file. + # Prefix the list here with "+" to use these queries and those in the config file. - - # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). - # If this step fails, then you should remove it and run the build manually (see below) - - name: Autobuild - uses: github/codeql-action/autobuild@v2 + # Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs + # queries: security-extended,security-and-quality - # ℹ️ Command-line programs to run using the OS shell. - # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun + # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). + # If this step fails, then you should remove it and run the build manually (see below) + - name: Autobuild + uses: github/codeql-action/autobuild@v2 - # If the Autobuild fails above, remove it and uncomment the following three lines. - # modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance. + # ℹ️ Command-line programs to run using the OS shell. + # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun - # - run: | - # echo "Run, Build Application using script" - # ./location_of_script_within_repo/buildscript.sh + # If the Autobuild fails above, remove it and uncomment the following three lines. + # modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance. - - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v2 - with: - category: "/language:${{matrix.language}}" + # - run: | + # echo "Run, Build Application using script" + # ./location_of_script_within_repo/buildscript.sh + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v2 + with: + category: "/language:${{matrix.language}}" diff --git a/CHANGELOG.md b/CHANGELOG.md index 51cfd50..0751c9e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,113 +1,159 @@ +## version 2.1.0 + +- 重构工厂模式、责任链模式 +- 去除多余模块 +- 增加所有测试用例单个提交的按钮,可以自己填写测试用例 +- 修改部分题目一键用例问题 + ## version 2.0.0 + - 重构 - 现在会从[zerotrac.github.io](https://zerotrac.github.io/leetcode_problem_rating/data.json)获取数据进行缓存 - 登录选择优化 + ## version 1.1.10 + - 更新数据 ## version 1.1.9 + - BWC90 & WC317 数据 ## version 1.1.8 + - WC316 数据 ## version 1.1.7 -- Windows环境使用VsCode自带node环境,测试用例解析问题 + +- Windows 环境使用 VsCode 自带 node 环境,测试用例解析问题 ## version 1.1.6 -- 尝试不需要安装node环境 + +- 尝试不需要安装 node 环境 ## version 1.1.5 -- 修复PreView Problem 题目元数据显示出错 + +- 修复 PreView Problem 题目元数据显示出错 ## version 1.1.4 + - BWC89 & WC315 数据 ## version 1.1.3 + - 修复每日一题隔天刷新问题 ## version 1.1.2 + - 去除多余客户端代码 ## version 1.1.1 + - 重新写原本的客户端 - 减少许多多余的包引用 ## version 1.0.24 -- 增加314期数据 + +- 增加 314 期数据 ## version 1.0.23 -- 修复README.md中GIF无法显示 + +- 修复 README.md 中 GIF 无法显示 ## version 1.0.22 + - 修复排序错误 -- 增加README.md说明 +- 增加 README.md 说明 + ## version 1.0.21 + - 修复提交全部用例问题 + ## version 1.0.20 + - 增加单次用例提交,全部用例提交的功能 ## version 1.0.19 + - 修复获取题解报错 + ## version 1.0.18 + - 增加更新状态栏的周赛数据显示 ## version 1.0.17 -- 更新312、313、双周88期 + +- 更新 312、313、双周 88 期 ## version 1.0.16 + - 修复测试用例字符串问题 - 每日一题提交后更新状态 ## version 1.0.15 -- 更换icon使得看起来不起眼 + +- 更换 icon 使得看起来不起眼 ## version 1.0.14 + - 安装插件检测 -- github问题报告模板 +- github 问题报告模板 ## version 1.0.13 + - 修复测试提交功能 ## version 1.0.12 + - 修复检出题目与标题对不上问题 ## version 1.0.11 + - 可以根据分数隐藏题目的设置 - 清除所有缓存功能 - 默认登录中国站 ## version 1.0.10 -- tag数据修复 -- 去除company分类 + +- tag 数据修复 +- 去除 company 分类 ## version 1.0.9 -- github提醒依赖安全更新 + +- github 提醒依赖安全更新 ## version 1.0.8 + - 增加精选合集分类 - 增加剑指、杯赛题目 - 每日一题 ## version 1.0.7 + - 更新分数数据 ## version 1.0.6 + - 随机一题根据竞赛分范围来获取 ## version 1.0.5 + - 获取每日一题 - 如果有竞赛分会根据竞赛分显示 绿、蓝、紫、黄、红 ## version 1.0.4 -- 修改padLevel错误 + +- 修改 padLevel 错误 - 自动化提交到市场 ## version 1.0.3 + - 题目颜色显示 ## version 1.0.2 + - 设置相关内容 ## version 1.0.1 + - 设置相关内容 diff --git a/README.md b/README.md index c97ebb1..4723698 100644 --- a/README.md +++ b/README.md @@ -11,53 +11,75 @@
# 概要设计 + - 在 VS Code 中解决 Leetcode 问题 - Leetcode 只提供了简单、中等、困难的难度区分。题目与题目之间难度差别很大,因此需要客观的分数对题目难度进行打分 - 增加中文官方的每日一题 -- 修复tag分类错误 +- 修复 tag 分类错误 - 增加精选分类 -- 增加剑指Offer、面试金典相关内容 +- 增加剑指 Offer、面试金典相关内容 - 增加一键提交全部题目测试用例功能 -- 尝试不需要额外安装node环境,使用vscode自带的node版本 -- 从[zerotrac.github.io](https://zerotrac.github.io/leetcode_problem_rating/data.json)获取数据进行缓存,数据更新时,可以尝试使用deleteAllCache,重新获取数据 +- 尝试不需要额外安装 node 环境,使用 vscode 自带的 node 版本 +- 从[zerotrac.github.io](https://zerotrac.github.io/leetcode_problem_rating/data.json)获取数据进行缓存,数据更新时,可以尝试使用 deleteAllCache,重新获取数据 +- 将所有提供的测试用例单独存放到代码下方,一键提交也会收集这部分的测试用例(简单去重()) # 关于本项目 + - [项目地址:https://github.com/ccagml/vscode-leetcode-problem-rating/](https://github.com/ccagml/vscode-leetcode-problem-rating/) - [报告问题](https://github.com/ccagml/vscode-leetcode-problem-rating/issues) - [疑难解答](https://github.com/LeetCode-OpenSource/vscode-leetcode/wiki/%E7%96%91%E9%9A%BE%E8%A7%A3%E7%AD%94) - [常见问题](https://github.com/LeetCode-OpenSource/vscode-leetcode/wiki/%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98) -- 趁着现在只有')) { - // - } else if (!['likes', 'dislikes'].every(p => p in _problem)) { - // - } else { - - underscore.extendOwn(problem, _problem); - return cb(null, problem); - } - } - this.next.getProblem(problem, needTranslation, function (e, _problem) { - if (e) return cb(e); - - that.saveProblem(_problem); - return cb(null, _problem); - }); - }; - - saveProblem = (problem) => { - const _problem = underscore.omit(problem, ['locked', 'state', 'starred']); - return storageUtils.setCache(helper.KEYS.problem(problem), _problem); - }; - - updateProblem = (problem, kv) => { - const problems = storageUtils.getCache(helper.KEYS.problems); - if (!problems) return false; - - const _problem = problems.find(x => x.id === problem.id); - if (!_problem) return false; - - underscore.extend(_problem, kv); - return storageUtils.setCache(helper.KEYS.problems, problems); - }; - - login = (user, cb) => { - this.logout(user, false); - this.next.login(user, function (e, user) { - if (e) return cb(e); - session.saveUser(user); - return cb(null, user); - }); - }; - - logout = (user, purge) => { - if (!user) user = session.getUser(); - if (purge) session.deleteUser(); - // NOTE: need invalidate any user related cache - session.deleteCodingSession(); - return user; - }; -} - - -export const pluginObj: CachePlugin = new CachePlugin(); diff --git a/src/childProcessCall/plugins/solution.discuss.ts b/src/childProcessCall/plugins/solution.discuss.ts deleted file mode 100644 index ac24a4f..0000000 --- a/src/childProcessCall/plugins/solution.discuss.ts +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Filename: https://github.com/ccagml/vscode-leetcode-problem-rating/src/childProcessCall/plugins/solution.discuss.ts - * Path: https://github.com/ccagml/vscode-leetcode-problem-rating - * Created Date: Thursday, October 27th 2022, 7:43:29 pm - * Author: ccagml - * - * Copyright (c) 2022 ccagml . All rights reserved. - */ - - -let request = require('request'); - - -import { log } from "../log"; -import { session } from "../session"; -import { MyPluginBase } from "../my_plugin_base"; - - - -class SolutionDiscuss extends MyPluginBase { - id = 200; - name = "solution.discuss"; - builtin = true; - constructor() { - super(); - } - - - getProblem = (problem, needTranslation, cb) => { - - this.next.getProblem(problem, needTranslation, function (e, problem) { - if (e || !session.argv.solution) return cb(e, problem); - - let lang = session.argv.lang; - getSolution(problem, lang, function (e, solution) { - if (e) return cb(e); - if (!solution) return log.error('Solution not found for ' + lang); - - let link = URL_DISCUSS.replace('$slug', problem.slug).replace('$id', solution.id); - let content = solution.post.content.replace(/\\n/g, '\n').replace(/\\t/g, '\t'); - - log.info(); - log.info(problem.name); - log.info(); - log.info(solution.title); - log.info(); - log.info(link); - log.info(); - log.info('* Lang: ' + lang); - log.info('* Author: ' + solution.post.author.username); - log.info('* Votes: ' + solution.post.voteCount); - log.info(); - log.info(content); - }); - }); - }; - -} - -let URL_DISCUSSES = 'https://leetcode.com/graphql'; -let URL_DISCUSS = 'https://leetcode.com/problems/$slug/discuss/$id'; - -function getSolution(problem, lang, cb) { - if (!problem) return cb(); - - if (lang === 'python3') lang = 'python'; - - let opts = { - url: URL_DISCUSSES, - json: true, - body: { - query: [ - 'query questionTopicsList($questionId: String!, $orderBy: TopicSortingOption, $skip: Int, $query: String, $first: Int!, $tags: [String!]) {', - ' questionTopicsList(questionId: $questionId, orderBy: $orderBy, skip: $skip, query: $query, first: $first, tags: $tags) {', - ' ...TopicsList', - ' }', - '}', - 'fragment TopicsList on TopicConnection {', - ' totalNum', - ' edges {', - ' node {', - ' id', - ' title', - ' post {', - ' content', - ' voteCount', - ' author {', - ' username', - ' }', - ' }', - ' }', - ' }', - '}' - ].join('\n'), - - operationName: 'questionTopicsList', - variables: JSON.stringify({ - query: '', - first: 1, - skip: 0, - orderBy: 'most_votes', - questionId: '' + problem.id, - tags: [lang] - }) - } - }; - request(opts, function (e, resp, body) { - if (e) return cb(e); - if (resp.statusCode !== 200) - return cb({ msg: 'http error', statusCode: resp.statusCode }); - - const solutions = body.data.questionTopicsList.edges; - const solution = solutions.length > 0 ? solutions[0].node : null; - return cb(null, solution); - }); -} - -export const pluginObj: SolutionDiscuss = new SolutionDiscuss(); diff --git a/src/childProcessCall/storageUtils.ts b/src/childProcessCall/storageUtils.ts deleted file mode 100644 index aae8e5e..0000000 --- a/src/childProcessCall/storageUtils.ts +++ /dev/null @@ -1,242 +0,0 @@ -/* - * Filename: https://github.com/ccagml/vscode-leetcode-problem-rating/src/childProcessCall/storageUtils.ts - * Path: https://github.com/ccagml/vscode-leetcode-problem-rating - * Created Date: Thursday, October 27th 2022, 7:43:29 pm - * Author: ccagml - * - * Copyright (c) 2022 ccagml . All rights reserved. - */ - - -let fs = require('fs'); -let os = require('os'); -let path = require('path'); - -let _ = require('underscore'); -let mkdirp = require('mkdirp'); - -export interface IMETA { - id: string - fid: string - lang: string -} - -//Object.assign({}, defaultMETA, {}) -export const defaultMETA: IMETA = { - id: "", - fid: "", - lang: "", -}; - -class StorageUtils { - public init() { - _.templateSettings = { - evaluate: /\{\{(.+?)\}\}/g, - interpolate: /\$\{(.+?)\}/g - }; - this.mkdir(this.homeDir()); - }; - - public isWindows() { - return process.platform === 'win32'; - }; - - public userHomeDir() { - return process.env.HOME || process.env.USERPROFILE; - }; - - public homeDir() { - return path.join(this.userHomeDir(), '.lcpr'); - }; - - public appDir() { - const config = require('./config'); - return path.join(this.homeDir(), config.app || 'leetcode'); - }; - - // 缓存目录 - public cacheDir() { - return path.join(this.appDir(), 'cache'); - }; - - // 代码目录 - public codeDir(dir) { - return path.join(__dirname, dir || ''); - }; - - // 缓存目录文件 - public cacheFile(k) { - return path.join(this.cacheDir(), k + '.json'); - }; - - // public configFile() { - // return path.join(this.homeDir(), 'config.json'); - // }; - - // 插件代码目录 - public listCodeDir(dir) { - dir = this.codeDir(dir); - let that = this; - return this.list(dir).map(function (f) { - const fullpath = path.join(dir, f); - const ext = path.extname(f); - const name = path.basename(f, ext); - - let data = null; - switch (ext) { - case '.js': data = require(fullpath).pluginObj; break; - case '.json': data = JSON.parse(that.getData(fullpath)); break; - } - return { name: name, data: data, file: f }; - }); - }; - - - public initCache() { - this.mkdir(this.cacheDir()); - }; - public deleteAllCache() { - this.listCache().forEach(value => { - this.delCache(value.name); - }); - }; - - public getCache(k) { - const fullpath = this.cacheFile(k); - if (!this.exist(fullpath)) return null; - - return JSON.parse(this.getData(fullpath)); - }; - - public setCache(k, v) { - const fullpath = this.cacheFile(k); - this.write(fullpath, JSON.stringify(v)); - return true; - }; - - public delCache(k) { - const fullpath = this.cacheFile(k); - if (!this.exist(fullpath)) return false; - - this.rm(fullpath); - return true; - }; - - public listCache(): Array{ - let that = this; - return this.list(this.cacheDir()) - .filter(x => path.extname(x) === '.json') - .map(function (filename) { - const k = path.basename(filename, '.json'); - const stat = that.stat(that.cacheFile(k)); - return { - name: k, - size: stat.size, - mtime: stat.mtime - }; - }); - }; - - public mkdir(fullpath) { - if (fs.existsSync(fullpath)) return; - mkdirp.sync(fullpath); - }; - - public exist(fullpath) { - return fs.existsSync(fullpath); - }; - - public rm(fullpath) { - return fs.unlinkSync(fullpath); - }; - - public mv(src, dst) { - return fs.renameSync(src, dst); - }; - - public list(dir) { - return fs.readdirSync(dir); - }; - - public stat(fullpath) { - return fs.statSync(fullpath); - }; - - public write(fullpath, data) { - return fs.writeFileSync(fullpath, data); - }; - - public name(fullpath) { - return path.basename(fullpath, path.extname(fullpath)); - }; - - public getData(fullpath) { - return fs.existsSync(fullpath) ? fs.readFileSync(fullpath).toString() : null; - }; - - // 获取要提交测试的数据 - public codeData(fullpath) { - const data = this.getData(fullpath); - - if (data === null) { - return null; - } - - const lines = data.split(/\r\n|\n|\r/); - const start = lines.findIndex(x => x.indexOf('@lc code=start') !== -1); - const end = lines.findIndex(x => x.indexOf('@lc code=end') !== -1); - - if (start !== -1 && end !== -1 && start + 1 <= end) { - return lines.slice(start + 1, end).join(os.EOL); - } - - return data; - }; - - // 加载输出模板数据 - public render(tpl, data) { - const tplfile = path.join(__dirname, "..", "..", "..", "resources", "templates", tpl + '.tpl'); - let result = _.template(this.getData(tplfile).replace(/\r\n/g, '\n'))(data); - if (this.isWindows()) { - result = result.replace(/\n/g, '\r\n'); - } else { - result = result.replace(/\r\n/g, '\n'); - } - return result; - }; - - public fmt(format, data) { - return _.template(format)(data); - }; - - // public metaByName(filename) { - // const m = Object.assign({}, defaultMETA, {}); - - // m.id = storageUtils.name(filename).split('.')[0]; - - - // if (filename.endsWith('.py3') || filename.endsWith('.python3.py')) - // m.lang = 'python3'; - // else - // m.lang = require('./helper').extToLang(filename); - - // return m; - // }; - - public meta(filename) { - const m = Object.assign({}, defaultMETA, {}); - const line = this.getData(filename).split('\n').find(x => x.indexOf(' @lc app=') >= 0) || ''; - // @lc app=leetcode.cn id=剑指 Offer II 116 lang=cpp - let id_right = line.split('id=')[1]; - let lang_cat = id_right.split('lang='); - let id = lang_cat[0].trim(); - let lang = lang_cat[1].trim(); - m.id = id; - m.fid = id; - m.lang = lang; - return m; - }; - -} - -export const storageUtils: StorageUtils = new StorageUtils(); diff --git a/src/controller/EventController.ts b/src/controller/EventController.ts index 4f55adf..9cbb350 100644 --- a/src/controller/EventController.ts +++ b/src/controller/EventController.ts @@ -10,12 +10,12 @@ import { eventService } from "../service/EventService"; // 事件的控制器 class EventContorller { - /** - * 监听事件 - */ - public add_event() { - eventService.add_event(); - } + /** + * 监听事件 + */ + public add_event() { + eventService.add_event(); + } } export const eventController: EventContorller = new EventContorller(); diff --git a/src/controller/FileButtonController.ts b/src/controller/FileButtonController.ts index c3f5cf0..a40764b 100644 --- a/src/controller/FileButtonController.ts +++ b/src/controller/FileButtonController.ts @@ -7,31 +7,29 @@ * Copyright (c) 2022 ccagml . All rights reserved. */ - import { ConfigurationChangeEvent, Disposable, languages, workspace } from "vscode"; import { fileButtonService } from "../service/FileButtonService"; // 文件按钮的控制器 class FileButtonController implements Disposable { + private registeredProvider: Disposable | undefined; + private configurationChangeListener: Disposable; - private registeredProvider: Disposable | undefined; - private configurationChangeListener: Disposable; - - constructor() { - this.configurationChangeListener = workspace.onDidChangeConfiguration((event: ConfigurationChangeEvent) => { - if (event.affectsConfiguration("leetcode-problem-rating.editor.shortcuts")) { - fileButtonService.refresh(); - } - }, this); + constructor() { + this.configurationChangeListener = workspace.onDidChangeConfiguration((event: ConfigurationChangeEvent) => { + if (event.affectsConfiguration("leetcode-problem-rating.editor.shortcuts")) { + fileButtonService.refresh(); + } + }, this); - this.registeredProvider = languages.registerCodeLensProvider({ scheme: "file" }, fileButtonService); - } + this.registeredProvider = languages.registerCodeLensProvider({ scheme: "file" }, fileButtonService); + } - public dispose(): void { - if (this.registeredProvider) { - this.registeredProvider.dispose(); - } - this.configurationChangeListener.dispose(); + public dispose(): void { + if (this.registeredProvider) { + this.registeredProvider.dispose(); } + this.configurationChangeListener.dispose(); + } } export const fileButtonController: FileButtonController = new FileButtonController(); diff --git a/src/controller/LoginController.ts b/src/controller/LoginController.ts index 2d50c0c..09b5184 100644 --- a/src/controller/LoginController.ts +++ b/src/controller/LoginController.ts @@ -19,172 +19,174 @@ import { statusBarService } from "../service/StatusBarService"; import { treeDataService } from "../service/TreeDataService"; import { getLeetCodeEndpoint } from "../utils/ConfigUtils"; - // 登录控制器 class LoginContorller { - constructor() { } - - // 登录操作 - public async signIn(): Promise { - const picks: Array > = []; - let qpOpiton: QuickPickOptions = { - title: "正在登录leetcode.com", - matchOnDescription: false, - matchOnDetail: false, - placeHolder: "请选择登录方式 正在登录leetcode.com", - }; - if (getLeetCodeEndpoint() == Endpoint.LeetCodeCN) { - picks.push({ - label: "LeetCode Account", - detail: "只能登录leetcode.cn", - value: "LeetCode", - }); - qpOpiton.title = "正在登录中文版leetcode.cn"; - qpOpiton.placeHolder = "请选择登录方式 正在登录中文版leetcode.cn"; - } - picks.push( - { - label: "Third-Party: GitHub", - detail: "Use GitHub account to login", - value: "GitHub", - }, - { - label: "Third-Party: LinkedIn", - detail: "Use LinkedIn account to login", - value: "LinkedIn", - }, - { - label: "LeetCode Cookie", - detail: "Use LeetCode cookie copied from browser to login", - value: "Cookie", - }, - ); - const choice: IQuickItemEx | undefined = await window.showQuickPick(picks, qpOpiton); - if (!choice) { - return; - } - const loginMethod: string = choice.value; - const commandArg: string | undefined = loginArgsMapping.get(loginMethod); - if (!commandArg) { - throw new Error(`不支持 "${loginMethod}" 方式登录`); - } - const isByCookie: boolean = loginMethod === "Cookie"; - const inMessage: string = isByCookie ? " 通过cookie登录" : "登录"; - try { - const userName: string | undefined = await new Promise(async (resolve: (res: string | undefined) => void, reject: (e: Error) => void): Promise => { - - const leetCodeBinaryPath: string = await executeService.getLeetCodeBinaryPath(); - - let childProc: cp.ChildProcess; - - if (systemUtils.useVscodeNode()) { - childProc = cp.fork(await executeService.getLeetCodeBinaryPath(), ["user", commandArg], { - silent: true, - env: createEnvOption(), - }); - } else { - if (systemUtils.useWsl()) { - childProc = cp.spawn("wsl", [executeService.node, leetCodeBinaryPath, "user", commandArg], { shell: true }); - } else { - childProc = cp.spawn(executeService.node, [leetCodeBinaryPath, "user", commandArg], { - shell: true, - env: createEnvOption(), - }); - } - - } - - childProc.stdout?.on("data", async (data: string | Buffer) => { - data = data.toString(); - // vscode.window.showInformationMessage(`cc login msg ${data}.`); - logOutput.append(data); - if (data.includes("twoFactorCode")) { - const twoFactor: string | undefined = await window.showInputBox({ - prompt: "Enter two-factor code.", - ignoreFocusOut: true, - validateInput: (s: string): string | undefined => s && s.trim() ? undefined : "The input must not be empty", - }); - if (!twoFactor) { - childProc.kill(); - return resolve(undefined); - } - childProc.stdin?.write(`${twoFactor}\n`); - } - - let successMatch; - try { - successMatch = JSON.parse(data); - } catch (e) { - successMatch = {}; - } - if (successMatch.code == 100) { - childProc.stdin?.end(); - return resolve(successMatch.user_name); - } else if (successMatch.code < 0) { - childProc.stdin?.end(); - return reject(new Error(successMatch.msg)); - } - }); - - childProc.stderr?.on("data", (data: string | Buffer) => logOutput.append(data.toString())); - - childProc.on("error", reject); - const name: string | undefined = await window.showInputBox({ - prompt: "Enter username or E-mail.", - ignoreFocusOut: true, - validateInput: (s: string): string | undefined => s && s.trim() ? undefined : "The input must not be empty", - }); - if (!name) { - childProc.kill(); - return resolve(undefined); - } - childProc.stdin?.write(`${name}\n`); - const pwd: string | undefined = await window.showInputBox({ - prompt: isByCookie ? "Enter cookie" : "Enter password.", - password: true, - ignoreFocusOut: true, - validateInput: (s: string): string | undefined => s ? undefined : isByCookie ? "Cookie must not be empty" : "Password must not be empty", - }); - if (!pwd) { - childProc.kill(); - return resolve(undefined); - } - childProc.stdin?.write(`${pwd}\n`); + constructor() {} + + // 登录操作 + public async signIn(): Promise { + const picks: Array > = []; + let qpOpiton: QuickPickOptions = { + title: "正在登录leetcode.com", + matchOnDescription: false, + matchOnDetail: false, + placeHolder: "请选择登录方式 正在登录leetcode.com", + }; + if (getLeetCodeEndpoint() == Endpoint.LeetCodeCN) { + picks.push({ + label: "LeetCode Account", + detail: "只能登录leetcode.cn", + value: "LeetCode", + }); + qpOpiton.title = "正在登录中文版leetcode.cn"; + qpOpiton.placeHolder = "请选择登录方式 正在登录中文版leetcode.cn"; + } + picks.push( + { + label: "Third-Party: GitHub", + detail: "Use GitHub account to login", + value: "GitHub", + }, + { + label: "Third-Party: LinkedIn", + detail: "Use LinkedIn account to login", + value: "LinkedIn", + }, + { + label: "LeetCode Cookie", + detail: "Use LeetCode cookie copied from browser to login", + value: "Cookie", + } + ); + const choice: IQuickItemEx | undefined = await window.showQuickPick(picks, qpOpiton); + if (!choice) { + return; + } + const loginMethod: string = choice.value; + const commandArg: string | undefined = loginArgsMapping.get(loginMethod); + if (!commandArg) { + throw new Error(`不支持 "${loginMethod}" 方式登录`); + } + const isByCookie: boolean = loginMethod === "Cookie"; + const inMessage: string = isByCookie ? " 通过cookie登录" : "登录"; + try { + const userName: string | undefined = await new Promise( + async (resolve: (res: string | undefined) => void, reject: (e: Error) => void): Promise => { + const leetCodeBinaryPath: string = await executeService.getLeetCodeBinaryPath(); + + let childProc: cp.ChildProcess; + + if (systemUtils.useVscodeNode()) { + childProc = cp.fork(await executeService.getLeetCodeBinaryPath(), ["user", commandArg], { + silent: true, + env: createEnvOption(), }); - if (userName) { - window.showInformationMessage(`${inMessage} 成功`); - eventService.emit("statusChanged", UserStatus.SignedIn, userName); + } else { + if (systemUtils.useWsl()) { + childProc = cp.spawn("wsl", [executeService.node, leetCodeBinaryPath, "user", commandArg], { + shell: true, + }); + } else { + childProc = cp.spawn(executeService.node, [leetCodeBinaryPath, "user", commandArg], { + shell: true, + env: createEnvOption(), + }); + } + } + + childProc.stdout?.on("data", async (data: string | Buffer) => { + data = data.toString(); + // vscode.window.showInformationMessage(`cc login msg ${data}.`); + logOutput.append(data); + if (data.includes("twoFactorCode")) { + const twoFactor: string | undefined = await window.showInputBox({ + prompt: "Enter two-factor code.", + ignoreFocusOut: true, + validateInput: (s: string): string | undefined => + s && s.trim() ? undefined : "The input must not be empty", + }); + if (!twoFactor) { + childProc.kill(); + return resolve(undefined); + } + childProc.stdin?.write(`${twoFactor}\n`); } - } catch (error) { - promptForOpenOutputChannel(`${inMessage}失败. 请看看控制台输出信息`, DialogType.error); - } - - } - // 登出 - public async signOut(): Promise { - try { - await executeService.signOut(); - window.showInformationMessage("成功登出"); - eventService.emit("statusChanged", UserStatus.SignedOut, undefined); - } catch (error) { - // promptForOpenOutputChannel(`Failed to signOut. Please open the output channel for details`, DialogType.error); + let successMatch; + try { + successMatch = JSON.parse(data); + } catch (e) { + successMatch = {}; + } + if (successMatch.code == 100) { + childProc.stdin?.end(); + return resolve(successMatch.user_name); + } else if (successMatch.code < 0) { + childProc.stdin?.end(); + return reject(new Error(successMatch.msg)); + } + }); + + childProc.stderr?.on("data", (data: string | Buffer) => logOutput.append(data.toString())); + + childProc.on("error", reject); + const name: string | undefined = await window.showInputBox({ + prompt: "Enter username or E-mail.", + ignoreFocusOut: true, + validateInput: (s: string): string | undefined => + s && s.trim() ? undefined : "The input must not be empty", + }); + if (!name) { + childProc.kill(); + return resolve(undefined); + } + childProc.stdin?.write(`${name}\n`); + const pwd: string | undefined = await window.showInputBox({ + prompt: isByCookie ? "Enter cookie" : "Enter password.", + password: true, + ignoreFocusOut: true, + validateInput: (s: string): string | undefined => + s ? undefined : isByCookie ? "Cookie must not be empty" : "Password must not be empty", + }); + if (!pwd) { + childProc.kill(); + return resolve(undefined); + } + childProc.stdin?.write(`${pwd}\n`); } + ); + if (userName) { + eventService.emit("statusChanged", UserStatus.SignedIn, userName); + window.showInformationMessage(`${inMessage} 成功`); + } + } catch (error) { + promptForOpenOutputChannel(`${inMessage}失败. 请看看控制台输出信息`, DialogType.error); } - - // 获取登录状态 - public async getLoginStatus() { - return await statusBarService.getLoginStatus(); - } - - // 删除所有缓存 - public async deleteAllCache(): Promise { - await this.signOut(); - await executeService.removeOldCache(); - await executeService.switchEndpoint(getLeetCodeEndpoint()); - await treeDataService.refresh(); + } + + // 登出 + public async signOut(): Promise { + try { + await executeService.signOut(); + window.showInformationMessage("成功登出"); + eventService.emit("statusChanged", UserStatus.SignedOut, undefined); + } catch (error) { + // promptForOpenOutputChannel(`Failed to signOut. Please open the output channel for details`, DialogType.error); } - + } + + // 获取登录状态 + public async getLoginStatus() { + return await statusBarService.getLoginStatus(); + } + + // 删除所有缓存 + public async deleteAllCache(): Promise { + await this.signOut(); + await executeService.removeOldCache(); + await executeService.switchEndpoint(getLeetCodeEndpoint()); + await treeDataService.refresh(); + } } export const loginContorller: LoginContorller = new LoginContorller(); diff --git a/src/controller/MainController.ts b/src/controller/MainController.ts index f5abdaa..d8a0ddf 100644 --- a/src/controller/MainController.ts +++ b/src/controller/MainController.ts @@ -11,32 +11,44 @@ import * as systemUtils from "../utils/SystemUtils"; import { executeService } from "../service/ExecuteService"; import { ExtensionContext } from "vscode"; import { treeDataService } from "../service/TreeDataService"; +import { logOutput } from "../utils/OutputUtils"; // 做杂活 class MainContorller { - constructor() { } + constructor() {} - /** - * 检查运行环境 - */ - public async checkNodeEnv(context: ExtensionContext) { - if (!systemUtils.useVscodeNode()) { - if (!await executeService.checkNodeEnv(context)) { - throw new Error("The environment doesn't meet requirements."); - } - } + /** + * 检查运行环境 + */ + public async checkNodeEnv(context: ExtensionContext) { + if (!systemUtils.useVscodeNode()) { + if (!(await executeService.checkNodeEnv(context))) { + throw new Error("The environment doesn't meet requirements."); + } } + } - // 初始化上下文 - public initialize(context: ExtensionContext) { - treeDataService.initialize(context); - } + public setGlobal(context: ExtensionContext) { + let cur_version: string = context.extension.packageJSON.version || "1.0.0"; + let cur_version_arr: Array = cur_version.split("."); + let cur_version_num = 0; + cur_version_arr.forEach((e) => { + cur_version_num *= 100; + cur_version_num += Number(e); + }); + logOutput.setLCPTCTX("version", cur_version_num); + } + // 初始化上下文 + public initialize(context: ExtensionContext) { + this.setGlobal(context); + treeDataService.initialize(context); + } - // 删除缓存 - public async deleteCache() { - await executeService.deleteCache(); - } + // 删除缓存 + public async deleteCache() { + await executeService.deleteCache(); + } } export const mainContorller: MainContorller = new MainContorller(); diff --git a/src/controller/TreeViewController.ts b/src/controller/TreeViewController.ts index 33df1ce..2122112 100644 --- a/src/controller/TreeViewController.ts +++ b/src/controller/TreeViewController.ts @@ -7,15 +7,48 @@ * Copyright (c) 2022 ccagml . All rights reserved. */ - import * as lodash from "lodash"; import * as path from "path"; import * as unescapeJS from "unescape-js"; import * as vscode from "vscode"; import { toNumber } from "lodash"; import { Disposable, Uri, window, QuickPickItem, workspace, WorkspaceConfiguration } from "vscode"; -import { SearchNode, userContestRankingObj, userContestRanKingBase, UserStatus, IProblem, IQuickItemEx, languages, Category, defaultProblem, ProblemState, SortingStrategy, SearchSetTypeName, RootNodeSort, SearchSetType, ISubmitEvent, SORT_ORDER, Endpoint, OpenOption, DialogType, DialogOptions } from "../model/Model"; -import { isHideSolvedProblem, isHideScoreProblem, getDescriptionConfiguration, isUseEndpointTranslation, enableSideMode, getPickOneByRankRangeMin, getPickOneByRankRangeMax, isShowLocked, updateSortingStrategy, getSortingStrategy, getLeetCodeEndpoint, openSettingsEditor } from "../utils/ConfigUtils"; +import { + SearchNode, + userContestRankingObj, + userContestRanKingBase, + UserStatus, + IProblem, + IQuickItemEx, + languages, + Category, + defaultProblem, + ProblemState, + SortingStrategy, + SearchSetTypeName, + RootNodeSort, + SearchSetType, + ISubmitEvent, + SORT_ORDER, + Endpoint, + OpenOption, + DialogType, + DialogOptions, +} from "../model/Model"; +import { + isHideSolvedProblem, + isHideScoreProblem, + getDescriptionConfiguration, + isUseEndpointTranslation, + enableSideMode, + getPickOneByRankRangeMin, + getPickOneByRankRangeMax, + isShowLocked, + updateSortingStrategy, + getSortingStrategy, + getLeetCodeEndpoint, + openSettingsEditor, +} from "../utils/ConfigUtils"; import { NodeModel } from "../model/NodeModel"; import { ISearchSet } from "../model/Model"; import { statusBarService } from "../service/StatusBarService"; @@ -34,1422 +67,1542 @@ import { fileButtonService } from "../service/FileButtonService"; import * as fse from "fs-extra"; import { submissionService } from "../service/SubmissionService"; - import * as os from "os"; import { getVsCodeConfig, getWorkspaceFolder } from "../utils/ConfigUtils"; - // 视图控制器 class TreeViewController implements Disposable { - private explorerNodeMap: Map = new Map (); - private companySet: Set = new Set (); - private tagSet: Set = new Set (); - private searchSet: Map = new Map (); - private waitTodayQuestion: boolean; - private waitUserContest: boolean; - - // 获取当前文件的路径 - public async getActiveFilePath(uri?: vscode.Uri): Promise { - let textEditor: vscode.TextEditor | undefined; - if (uri) { - textEditor = await vscode.window.showTextDocument(uri, { preview: false }); - } else { - textEditor = vscode.window.activeTextEditor; - } - - if (!textEditor) { - return undefined; - } - if (textEditor.document.isDirty && !await textEditor.document.save()) { - vscode.window.showWarningMessage("请先保存当前文件"); - return undefined; - } - return systemUtils.useWsl() ? systemUtils.toWslPath(textEditor.document.uri.fsPath) : textEditor.document.uri.fsPath; + private explorerNodeMap: Map = new Map (); + private companySet: Set = new Set (); + private tagSet: Set = new Set (); + private searchSet: Map = new Map (); + private waitTodayQuestion: boolean; + private waitUserContest: boolean; + + // 获取当前文件的路径 + public async getActiveFilePath(uri?: vscode.Uri): Promise { + let textEditor: vscode.TextEditor | undefined; + if (uri) { + textEditor = await vscode.window.showTextDocument(uri, { + preview: false, + }); + } else { + textEditor = vscode.window.activeTextEditor; } - // 提交问题 - public async submitSolution(uri?: vscode.Uri): Promise { - if (!statusBarService.getUser()) { - promptForSignIn(); - return; - } - - const filePath: string | undefined = await this.getActiveFilePath(uri); - if (!filePath) { - return; - } - - try { - const result: string = await executeService.submitSolution(filePath); - submissionService.show(result); - eventService.emit("submit", submissionService.getSubmitEvent()); - } catch (error) { - await promptForOpenOutputChannel("提交出错了. 请查看控制台信息~", DialogType.error); - return; - } - - treeDataService.refresh(); + if (!textEditor) { + return undefined; } - - - // 提交测试用例 - public async testSolution(uri?: vscode.Uri): Promise { - try { - if (statusBarService.getStatus() === UserStatus.SignedOut) { - return; - } - - const filePath: string | undefined = await this.getActiveFilePath(uri); - if (!filePath) { - return; - } - const picks: Array > = []; - picks.push( - // { - // label: "$(three-bars) Default test cases", - // description: "", - // detail: "默认用例", - // value: ":default", - // }, - { - label: "$(pencil) Write directly...", - description: "", - detail: "输入框的测试用例", - value: ":direct", - }, - { - label: "$(file-text) Browse...", - description: "", - detail: "文件中的测试用例", - value: ":file", - }, - // { - // label: "All Default test cases...", - // description: "", - // detail: "所有的测试用例", - // value: ":alldefault", - // }, - ); - const choice: IQuickItemEx | undefined = await vscode.window.showQuickPick(picks); - if (!choice) { - return; - } - - let result: string | undefined; - let testString: string | undefined; - let testFile: vscode.Uri[] | undefined; - switch (choice.value) { - case ":default": - result = await executeService.testSolution(filePath); - break; - case ":direct": - testString = await vscode.window.showInputBox({ - prompt: "Enter the test cases.", - validateInput: (s: string): string | undefined => s && s.trim() ? undefined : "Test case must not be empty.", - placeHolder: "Example: [1,2,3]\\n4", - ignoreFocusOut: true, - }); - if (testString) { - result = await executeService.testSolution(filePath, this.parseTestString(testString)); - } - break; - case ":file": - testFile = await this.showFileSelectDialog(filePath); - if (testFile && testFile.length) { - const input: string = (await fse.readFile(testFile[0].fsPath, "utf-8")).trim(); - if (input) { - result = await executeService.testSolution(filePath, this.parseTestString(input.replace(/\r?\n/g, "\\n"))); - } else { - vscode.window.showErrorMessage("The selected test file must not be empty."); - } - } - break; - case ":alldefault": - result = await executeService.testSolution(filePath, undefined, true); - break; - default: - break; - } - if (!result) { - return; - } - submissionService.show(result); - eventService.emit("submit", submissionService.getSubmitEvent()); - } catch (error) { - await promptForOpenOutputChannel("提交测试出错了. 请查看控制台信息~", DialogType.error); - } + if (textEditor.document.isDirty && !(await textEditor.document.save())) { + vscode.window.showWarningMessage("请先保存当前文件"); + return undefined; } - public async showFileSelectDialog(fsPath?: string): Promise { - const defaultUri: vscode.Uri | undefined = this.getBelongingWorkspaceFolderUri(fsPath); - const options: vscode.OpenDialogOptions = { - defaultUri, - canSelectFiles: true, - canSelectFolders: false, - canSelectMany: false, - openLabel: "Select", - }; - return await vscode.window.showOpenDialog(options); + return systemUtils.useWsl() + ? systemUtils.toWslPath(textEditor.document.uri.fsPath) + : textEditor.document.uri.fsPath; + } + + // 提交问题 + public async submitSolution(uri?: vscode.Uri): Promise { + if (!statusBarService.getUser()) { + promptForSignIn(); + return; } - - public async testSolutionDefault(uri?: vscode.Uri, allCase?: boolean): Promise { - try { - if (statusBarService.getStatus() === UserStatus.SignedOut) { - return; - } - - const filePath: string | undefined = await this.getActiveFilePath(uri); - if (!filePath) { - return; - } - - let result: string | undefined = await executeService.testSolution(filePath, undefined, allCase || false); - if (!result) { - return; - } - submissionService.show(result); - eventService.emit("submit", submissionService.getSubmitEvent()); - } catch (error) { - await promptForOpenOutputChannel("提交测试出错了. 请查看控制台信息~", DialogType.error); - } + const filePath: string | undefined = await this.getActiveFilePath(uri); + if (!filePath) { + return; } - public usingCmd(): boolean { - const comSpec: string | undefined = process.env.ComSpec; - // 'cmd.exe' is used as a fallback if process.env.ComSpec is unavailable. - if (!comSpec) { - return true; - } - - if (comSpec.indexOf("cmd.exe") > -1) { - return true; - } - return false; + try { + const result: string = await executeService.submitSolution(filePath); + submissionService.show(result); + eventService.emit("submit", submissionService.getSubmitEvent()); + } catch (error) { + await promptForOpenOutputChannel("提交出错了. 请查看控制台信息~", DialogType.error); + return; } - public parseTestString(test: string): string { - if (systemUtils.useWsl() || !systemUtils.isWindows()) { - if (systemUtils.useVscodeNode()) { - return `${test}`; - } - return `'${test}'`; - } - - if (this.usingCmd()) { - // 一般需要走进这里, 除非改了 环境变量ComSpec的值 - if (systemUtils.useVscodeNode()) { - //eslint-disable-next-line - return `${test.replace(/"/g, '\"')}`; - } - return `"${test.replace(/"/g, '\\"')}"`; - } else { - if (systemUtils.useVscodeNode()) { - //eslint-disable-next-line - return `${test.replace(/"/g, '\"')}`; + treeDataService.refresh(); + } + + // 提交测试用例 + public async testSolution(uri?: vscode.Uri): Promise { + try { + if (statusBarService.getStatus() === UserStatus.SignedOut) { + return; + } + + const filePath: string | undefined = await this.getActiveFilePath(uri); + if (!filePath) { + return; + } + const picks: Array > = []; + picks.push( + // { + // label: "$(three-bars) Default test cases", + // description: "", + // detail: "默认用例", + // value: ":default", + // }, + { + label: "$(pencil) Write directly...", + description: "", + detail: "输入框的测试用例", + value: ":direct", + }, + { + label: "$(file-text) Browse...", + description: "", + detail: "文件中的测试用例", + value: ":file", + } + // { + // label: "All Default test cases...", + // description: "", + // detail: "所有的测试用例", + // value: ":alldefault", + // }, + ); + const choice: IQuickItemEx | undefined = await vscode.window.showQuickPick(picks); + if (!choice) { + return; + } + + let result: string | undefined; + let testString: string | undefined; + let testFile: vscode.Uri[] | undefined; + switch (choice.value) { + case ":default": + result = await executeService.testSolution(filePath); + break; + case ":direct": + testString = await vscode.window.showInputBox({ + prompt: "Enter the test cases.", + validateInput: (s: string): string | undefined => + s && s.trim() ? undefined : "Test case must not be empty.", + placeHolder: "Example: [1,2,3]\\n4", + ignoreFocusOut: true, + }); + if (testString) { + result = await executeService.testSolution(filePath, this.parseTestString(testString)); + } + break; + case ":file": + testFile = await this.showFileSelectDialog(filePath); + if (testFile && testFile.length) { + const input: string = (await fse.readFile(testFile[0].fsPath, "utf-8")).trim(); + if (input) { + result = await executeService.testSolution( + filePath, + this.parseTestString(input.replace(/\r?\n/g, "\\n")) + ); + } else { + vscode.window.showErrorMessage("The selected test file must not be empty."); } - return `'${test.replace(/"/g, '\\"')}'`; - } + } + break; + case ":alldefault": + result = await executeService.testSolution(filePath, undefined, true); + break; + default: + break; + } + if (!result) { + return; + } + submissionService.show(result); + eventService.emit("submit", submissionService.getSubmitEvent()); + } catch (error) { + await promptForOpenOutputChannel("提交测试出错了. 请查看控制台信息~", DialogType.error); } - - - public async switchEndpoint(): Promise { - const isCnEnabled: boolean = getLeetCodeEndpoint() === Endpoint.LeetCodeCN; - const picks: Array > = []; - picks.push( - { - label: `${isCnEnabled ? "" : "$(check) "}LeetCode`, - description: "leetcode.com", - detail: `Enable LeetCode.com US`, - value: Endpoint.LeetCode, - }, - { - label: `${isCnEnabled ? "$(check) " : ""}力扣`, - description: "leetcode.cn", - detail: `启用中国版 LeetCode.cn`, - value: Endpoint.LeetCodeCN, - }, - ); - const choice: IQuickItemEx | undefined = await vscode.window.showQuickPick(picks); - if (!choice || choice.value === getLeetCodeEndpoint()) { - return; - } - const leetCodeConfig: vscode.WorkspaceConfiguration = vscode.workspace.getConfiguration("leetcode-problem-rating"); - try { - const endpoint: string = choice.value; - await executeService.switchEndpoint(endpoint); - await leetCodeConfig.update("endpoint", endpoint, true /* UserSetting */); - vscode.window.showInformationMessage(`Switched the endpoint to ${endpoint}`); - } catch (error) { - await promptForOpenOutputChannel("切换站点出错. 请查看控制台信息~", DialogType.error); - } - - try { - await vscode.commands.executeCommand("leetcode.signout"); - await executeService.deleteCache(); - await promptForSignIn(); - } catch (error) { - await promptForOpenOutputChannel("登录失败. 请查看控制台信息~", DialogType.error); - } + } + public async showFileSelectDialog(fsPath?: string): Promise { + const defaultUri: vscode.Uri | undefined = this.getBelongingWorkspaceFolderUri(fsPath); + const options: vscode.OpenDialogOptions = { + defaultUri, + canSelectFiles: true, + canSelectFolders: false, + canSelectMany: false, + openLabel: "Select", + }; + return await vscode.window.showOpenDialog(options); + } + + public async testSolutionDefault(uri?: vscode.Uri, allCase?: boolean): Promise { + try { + if (statusBarService.getStatus() === UserStatus.SignedOut) { + return; + } + + const filePath: string | undefined = await this.getActiveFilePath(uri); + if (!filePath) { + return; + } + + let result: string | undefined = await executeService.testSolution(filePath, undefined, allCase || false); + if (!result) { + return; + } + submissionService.show(result); + eventService.emit("submit", submissionService.getSubmitEvent()); + } catch (error) { + await promptForOpenOutputChannel("提交测试出错了. 请查看控制台信息~", DialogType.error); } - - - public async switchSortingStrategy(): Promise { - const currentStrategy: SortingStrategy = getSortingStrategy(); - const picks: Array > = []; - picks.push( - ...SORT_ORDER.map((s: SortingStrategy) => { - return { - label: `${currentStrategy === s ? "$(check)" : " "} ${s}`, - value: s, - }; - }), - ); - - const choice: IQuickItemEx | undefined = await vscode.window.showQuickPick(picks); - if (!choice || choice.value === currentStrategy) { - return; - } - - await updateSortingStrategy(choice.value, true); - await treeDataService.refresh(); + } + + public async testSolutionArea(uri?: vscode.Uri, testcase?: string): Promise { + try { + if (statusBarService.getStatus() === UserStatus.SignedOut) { + return; + } + + const filePath: string | undefined = await this.getActiveFilePath(uri); + if (!filePath) { + return; + } + + let result: string | undefined = await executeService.testSolution(filePath, testcase, false); + if (!result) { + return; + } + submissionService.show(result); + eventService.emit("submit", submissionService.getSubmitEvent()); + } catch (error) { + await promptForOpenOutputChannel("提交测试出错了. 请查看控制台信息~", DialogType.error); } + } - - public async addFavorite(node: NodeModel): Promise { - try { - await executeService.toggleFavorite(node, true); - await treeDataService.refresh(); - if (isStarShortcut()) { - fileButtonService.refresh(); - } - } catch (error) { - await promptForOpenOutputChannel("添加喜欢题目失败. 请查看控制台信息~", DialogType.error); - } + public usingCmd(): boolean { + const comSpec: string | undefined = process.env.ComSpec; + // 'cmd.exe' is used as a fallback if process.env.ComSpec is unavailable. + if (!comSpec) { + return true; } - public async removeFavorite(node: NodeModel): Promise { - try { - await executeService.toggleFavorite(node, false); - await treeDataService.refresh(); - if (isStarShortcut()) { - fileButtonService.refresh(); - } - } catch (error) { - await promptForOpenOutputChannel("移除喜欢题目失败. 请查看控制台信息~", DialogType.error); - } + if (comSpec.indexOf("cmd.exe") > -1) { + return true; } - - public async listProblems(): Promise { - try { - if (statusBarService.getStatus() === UserStatus.SignedOut) { - return []; - } - - const showLockedFlag: boolean = isShowLocked(); - const useEndpointTranslation: boolean = isUseEndpointTranslation(); - const result: string = await executeService.listProblems(showLockedFlag, useEndpointTranslation); - const all_problem_info = JSON.parse(result); - const problems: IProblem[] = []; - const AllScoreData = treeDataService.getScoreData(); - // 增加直接在线获取分数数据 - const AllScoreDataOnline = await treeDataService.getScoreDataOnline(); - for (const p of all_problem_info) { - problems.push({ - id: p.fid, - qid: p.id, - isFavorite: p.starred, - locked: p.locked, - state: this.parseProblemState(p.state), - name: p.name, - difficulty: p.level, - passRate: p.percent, - companies: p.companies || [], - tags: treeDataService.getTagsData(p.fid), - scoreData: AllScoreDataOnline.get(p.fid) || AllScoreData.get(p.fid), - isSearchResult: false, - input: "", - rootNodeSortId: RootNodeSort.ZERO, - todayData: undefined, - }); - } - return problems.reverse(); - } catch (error) { - await promptForOpenOutputChannel("获取题目失败. 请查看控制台信息~", DialogType.error); - return []; - } + return false; + } + + public parseTestString(test: string): string { + if (systemUtils.useWsl() || !systemUtils.isWindows()) { + if (systemUtils.useVscodeNode()) { + return `${test}`; + } + return `'${test}'`; } - public parseProblemState(stateOutput: string): ProblemState { - if (!stateOutput) { - return ProblemState.Unknown; - } - switch (stateOutput.trim()) { - case "v": - case "✔": - case "√": - case "ac": - return ProblemState.AC; - case "X": - case "✘": - case "×": - case "notac": - return ProblemState.NotAC; - default: - return ProblemState.Unknown; - } + if (this.usingCmd()) { + // 一般需要走进这里, 除非改了 环境变量ComSpec的值 + if (systemUtils.useVscodeNode()) { + //eslint-disable-next-line + return `${test.replace(/"/g, '"')}`; + } + return `"${test.replace(/"/g, '\\"')}"`; + } else { + if (systemUtils.useVscodeNode()) { + //eslint-disable-next-line + return `${test.replace(/"/g, '"')}`; + } + return `'${test.replace(/"/g, '\\"')}'`; + } + } + + public async switchEndpoint(): Promise { + const isCnEnabled: boolean = getLeetCodeEndpoint() === Endpoint.LeetCodeCN; + const picks: Array > = []; + picks.push( + { + label: `${isCnEnabled ? "" : "$(check) "}LeetCode`, + description: "leetcode.com", + detail: `Enable LeetCode.com US`, + value: Endpoint.LeetCode, + }, + { + label: `${isCnEnabled ? "$(check) " : ""}力扣`, + description: "leetcode.cn", + detail: `启用中国版 LeetCode.cn`, + value: Endpoint.LeetCodeCN, + } + ); + const choice: IQuickItemEx | undefined = await vscode.window.showQuickPick(picks); + if (!choice || choice.value === getLeetCodeEndpoint()) { + return; + } + const leetCodeConfig: vscode.WorkspaceConfiguration = vscode.workspace.getConfiguration("leetcode-problem-rating"); + try { + const endpoint: string = choice.value; + await executeService.switchEndpoint(endpoint); + await leetCodeConfig.update("endpoint", endpoint, true /* UserSetting */); + vscode.window.showInformationMessage(`Switched the endpoint to ${endpoint}`); + } catch (error) { + await promptForOpenOutputChannel("切换站点出错. 请查看控制台信息~", DialogType.error); } + try { + await vscode.commands.executeCommand("leetcode.signout"); + await executeService.deleteCache(); + await promptForSignIn(); + } catch (error) { + await promptForOpenOutputChannel("登录失败. 请查看控制台信息~", DialogType.error); + } + } + + public async switchSortingStrategy(): Promise { + const currentStrategy: SortingStrategy = getSortingStrategy(); + const picks: Array > = []; + picks.push( + ...SORT_ORDER.map((s: SortingStrategy) => { + return { + label: `${currentStrategy === s ? "$(check)" : " "} ${s}`, + value: s, + }; + }) + ); - public async switchDefaultLanguage(): Promise { - const leetCodeConfig: WorkspaceConfiguration = workspace.getConfiguration("leetcode-problem-rating"); - const defaultLanguage: string | undefined = leetCodeConfig.get ("defaultLanguage"); - const languageItems: QuickPickItem[] = []; - for (const language of languages) { - languageItems.push({ - label: language, - description: defaultLanguage === language ? "Currently used" : undefined, - }); - } - // Put the default language at the top of the list - languageItems.sort((a: QuickPickItem, b: QuickPickItem) => { - if (a.description) { - return Number.MIN_SAFE_INTEGER; - } else if (b.description) { - return Number.MAX_SAFE_INTEGER; - } - return a.label.localeCompare(b.label); - }); + const choice: IQuickItemEx | undefined = await vscode.window.showQuickPick(picks); + if (!choice || choice.value === currentStrategy) { + return; + } - const selectedItem: QuickPickItem | undefined = await window.showQuickPick(languageItems, { - placeHolder: "请设置默认语言", - ignoreFocusOut: true, + await updateSortingStrategy(choice.value, true); + await treeDataService.refresh(); + } + + public async addFavorite(node: NodeModel): Promise { + try { + await executeService.toggleFavorite(node, true); + await treeDataService.refresh(); + if (isStarShortcut()) { + fileButtonService.refresh(); + } + } catch (error) { + await promptForOpenOutputChannel("添加喜欢题目失败. 请查看控制台信息~", DialogType.error); + } + } + + public async removeFavorite(node: NodeModel): Promise { + try { + await executeService.toggleFavorite(node, false); + await treeDataService.refresh(); + if (isStarShortcut()) { + fileButtonService.refresh(); + } + } catch (error) { + await promptForOpenOutputChannel("移除喜欢题目失败. 请查看控制台信息~", DialogType.error); + } + } + + public async listProblems(): Promise { + try { + if (statusBarService.getStatus() === UserStatus.SignedOut) { + return []; + } + + const showLockedFlag: boolean = isShowLocked(); + const useEndpointTranslation: boolean = isUseEndpointTranslation(); + const result: string = await executeService.listProblems(showLockedFlag, useEndpointTranslation); + const all_problem_info = JSON.parse(result); + const problems: IProblem[] = []; + const AllScoreData = treeDataService.getScoreData(); + // 增加直接在线获取分数数据 + const AllScoreDataOnline = await treeDataService.getScoreDataOnline(); + for (const p of all_problem_info) { + problems.push({ + id: p.fid, + qid: p.id, + isFavorite: p.starred, + locked: p.locked, + state: this.parseProblemState(p.state), + name: p.name, + difficulty: p.level, + passRate: p.percent, + companies: p.companies || [], + tags: treeDataService.getTagsData(p.fid), + scoreData: AllScoreDataOnline.get(p.fid) || AllScoreData.get(p.fid), + isSearchResult: false, + input: "", + rootNodeSortId: RootNodeSort.ZERO, + todayData: undefined, }); - - if (!selectedItem) { - return; - } - - leetCodeConfig.update("defaultLanguage", selectedItem.label, true /* Global */); - window.showInformationMessage(`设置默认语言 ${selectedItem.label} 成功`); + } + return problems.reverse(); + } catch (error) { + await promptForOpenOutputChannel("获取题目失败. 请查看控制台信息~", DialogType.error); + return []; } + } - - public isSubFolder(from: string, to: string): boolean { - const relative: string = path.relative(from, to); - if (relative === "") { - return true; - } - return !relative.startsWith("..") && !path.isAbsolute(relative); - } - - public async determineLeetCodeFolder(): Promise { - let result: string; - const picks: Array > = []; - picks.push( - { - label: `Default location`, - detail: `${path.join(os.homedir(), ".leetcode")}`, - value: `${path.join(os.homedir(), ".leetcode")}`, - }, - { - label: "$(file-directory) Browse...", - value: ":browse", - }, - ); - const choice: IQuickItemEx | undefined = await vscode.window.showQuickPick( - picks, - { placeHolder: "Select where you would like to save your LeetCode files" }, - ); - if (!choice) { - result = ""; - } else if (choice.value === ":browse") { - const directory: vscode.Uri[] | undefined = await this.showDirectorySelectDialog(); - if (!directory || directory.length < 1) { - result = ""; - } else { - result = directory[0].fsPath; - } - } else { - result = choice.value; - } - - getVsCodeConfig().update("workspaceFolder", result, vscode.ConfigurationTarget.Global); - - return result; + public parseProblemState(stateOutput: string): ProblemState { + if (!stateOutput) { + return ProblemState.Unknown; } - - public async showDirectorySelectDialog(fsPath?: string): Promise { - const defaultUri: vscode.Uri | undefined = this.getBelongingWorkspaceFolderUri(fsPath); - const options: vscode.OpenDialogOptions = { - defaultUri, - canSelectFiles: false, - canSelectFolders: true, - canSelectMany: false, - openLabel: "Select", - }; - return await vscode.window.showOpenDialog(options); + switch (stateOutput.trim()) { + case "v": + case "✔": + case "√": + case "ac": + return ProblemState.AC; + case "X": + case "✘": + case "×": + case "notac": + return ProblemState.NotAC; + default: + return ProblemState.Unknown; } - - public getBelongingWorkspaceFolderUri(fsPath: string | undefined): vscode.Uri | undefined { - let defaultUri: vscode.Uri | undefined; - if (fsPath) { - const workspaceFolder: vscode.WorkspaceFolder | undefined = vscode.workspace.getWorkspaceFolder(vscode.Uri.file(fsPath)); - if (workspaceFolder) { - defaultUri = workspaceFolder.uri; - } - } - return defaultUri; + } + + public async switchDefaultLanguage(): Promise { + const leetCodeConfig: WorkspaceConfiguration = workspace.getConfiguration("leetcode-problem-rating"); + const defaultLanguage: string | undefined = leetCodeConfig.get ("defaultLanguage"); + const languageItems: QuickPickItem[] = []; + for (const language of languages) { + languageItems.push({ + label: language, + description: defaultLanguage === language ? "Currently used" : undefined, + }); + } + // Put the default language at the top of the list + languageItems.sort((a: QuickPickItem, b: QuickPickItem) => { + if (a.description) { + return Number.MIN_SAFE_INTEGER; + } else if (b.description) { + return Number.MAX_SAFE_INTEGER; + } + return a.label.localeCompare(b.label); + }); + + const selectedItem: QuickPickItem | undefined = await window.showQuickPick(languageItems, { + placeHolder: "请设置默认语言", + ignoreFocusOut: true, + }); + + if (!selectedItem) { + return; } + leetCodeConfig.update("defaultLanguage", selectedItem.label, true /* Global */); + window.showInformationMessage(`设置默认语言 ${selectedItem.label} 成功`); + } - public async searchProblem(): Promise { - if (!statusBarService.getUser()) { - promptForSignIn(); - return; - } - - const picks: Array > = []; - picks.push( - { - label: `题目id查询`, - detail: `通过题目id查询`, - value: `byid`, - }, - { - label: `分数范围查询`, - detail: `例如 1500-1600`, - value: `range`, - }, - { - label: `周赛期数查询`, - detail: `周赛期数查询`, - value: `contest`, - }, - { - label: `测试api`, - detail: `测试api`, - value: `testapi`, - } - // , - // { - // label: `每日一题`, - // detail: `每日一题`, - // value: `today`, - // }, - // { - // label: `查询自己竞赛信息`, - // detail: `查询自己竞赛信息`, - // value: `userContest`, - // } - ); - const choice: IQuickItemEx | undefined = await vscode.window.showQuickPick( - picks, - { title: "选择查询选项" }, - ); - if (!choice) { - return; - } - if (choice.value == "byid") { - await this.searchProblemByID(); - } else if (choice.value == "range") { - await this.searchScoreRange(); - } else if (choice.value == "contest") { - await this.searchContest(); - } else if (choice.value == "today") { - await this.searchToday(); - } else if (choice.value == "userContest") { - await this.searchUserContest(); - } else if (choice.value == "testapi") { - await this.testapi(); - } + public isSubFolder(from: string, to: string): boolean { + const relative: string = path.relative(from, to); + if (relative === "") { + return true; + } + return !relative.startsWith("..") && !path.isAbsolute(relative); + } + + public async determineLeetCodeFolder(): Promise { + let result: string; + const picks: Array > = []; + picks.push( + { + label: `Default location`, + detail: `${path.join(os.homedir(), ".leetcode")}`, + value: `${path.join(os.homedir(), ".leetcode")}`, + }, + { + label: "$(file-directory) Browse...", + value: ":browse", + } + ); + const choice: IQuickItemEx | undefined = await vscode.window.showQuickPick(picks, { + placeHolder: "Select where you would like to save your LeetCode files", + }); + if (!choice) { + result = ""; + } else if (choice.value === ":browse") { + const directory: vscode.Uri[] | undefined = await this.showDirectorySelectDialog(); + if (!directory || directory.length < 1) { + result = ""; + } else { + result = directory[0].fsPath; + } + } else { + result = choice.value; + } + getVsCodeConfig().update("workspaceFolder", result, vscode.ConfigurationTarget.Global); + + return result; + } + + public async showDirectorySelectDialog(fsPath?: string): Promise { + const defaultUri: vscode.Uri | undefined = this.getBelongingWorkspaceFolderUri(fsPath); + const options: vscode.OpenDialogOptions = { + defaultUri, + canSelectFiles: false, + canSelectFolders: true, + canSelectMany: false, + openLabel: "Select", + }; + return await vscode.window.showOpenDialog(options); + } + + public getBelongingWorkspaceFolderUri(fsPath: string | undefined): vscode.Uri | undefined { + let defaultUri: vscode.Uri | undefined; + if (fsPath) { + const workspaceFolder: vscode.WorkspaceFolder | undefined = vscode.workspace.getWorkspaceFolder( + vscode.Uri.file(fsPath) + ); + if (workspaceFolder) { + defaultUri = workspaceFolder.uri; + } } + return defaultUri; + } - public async showSolution(input: NodeModel | vscode.Uri): Promise { - let problemInput: string | undefined; - if (input instanceof NodeModel) { // Triggerred from explorer - problemInput = input.qid; - } else if (input instanceof vscode.Uri) { // Triggerred from Code Lens/context menu - if (systemUtils.useVscodeNode()) { - problemInput = `${input.fsPath}`; - } else { - problemInput = `"${input.fsPath}"`; - if (systemUtils.useWsl()) { - problemInput = await systemUtils.toWslPath(input.fsPath); - } - } - } else if (!input) { // Triggerred from command - problemInput = await this.getActiveFilePath(); - } + public async searchProblem(): Promise { + if (!statusBarService.getUser()) { + promptForSignIn(); + return; + } - if (!problemInput) { - vscode.window.showErrorMessage("Invalid input to fetch the solution data."); - return; - } + const picks: Array > = []; + picks.push( + { + label: `题目id查询`, + detail: `通过题目id查询`, + value: `byid`, + }, + { + label: `分数范围查询`, + detail: `例如 1500-1600`, + value: `range`, + }, + { + label: `周赛期数查询`, + detail: `周赛期数查询`, + value: `contest`, + }, + { + label: `测试api`, + detail: `测试api`, + value: `testapi`, + } + // , + // { + // label: `每日一题`, + // detail: `每日一题`, + // value: `today`, + // }, + // { + // label: `查询自己竞赛信息`, + // detail: `查询自己竞赛信息`, + // value: `userContest`, + // } + ); + const choice: IQuickItemEx | undefined = await vscode.window.showQuickPick(picks, { + title: "选择查询选项", + }); + if (!choice) { + return; + } + if (choice.value == "byid") { + await this.searchProblemByID(); + } else if (choice.value == "range") { + await this.searchScoreRange(); + } else if (choice.value == "contest") { + await this.searchContest(); + } else if (choice.value == "today") { + await this.searchToday(); + } else if (choice.value == "userContest") { + await this.searchUserContest(); + } else if (choice.value == "testapi") { + await this.testapi(); + } + } + + public async showSolution(input: NodeModel | vscode.Uri): Promise { + let problemInput: string | undefined; + if (input instanceof NodeModel) { + // Triggerred from explorer + problemInput = input.qid; + } else if (input instanceof vscode.Uri) { + // Triggerred from Code Lens/context menu + if (systemUtils.useVscodeNode()) { + problemInput = `${input.fsPath}`; + } else { + problemInput = `"${input.fsPath}"`; + if (systemUtils.useWsl()) { + problemInput = await systemUtils.toWslPath(input.fsPath); + } + } + } else if (!input) { + // Triggerred from command + problemInput = await this.getActiveFilePath(); + } - const language: string | undefined = await this.fetchProblemLanguage(); - if (!language) { - return; - } - try { - const needTranslation: boolean = isUseEndpointTranslation(); - const solution: string = await executeService.showSolution(problemInput, language, needTranslation); - solutionService.show(unescapeJS(solution)); - } catch (error) { - logOutput.appendLine(error.toString()); - await promptForOpenOutputChannel("Failed to fetch the top voted solution. 请查看控制台信息~", DialogType.error); - } + if (!problemInput) { + vscode.window.showErrorMessage("Invalid input to fetch the solution data."); + return; } + const language: string | undefined = await this.fetchProblemLanguage(); + if (!language) { + return; + } + try { + const needTranslation: boolean = isUseEndpointTranslation(); + const solution: string = await executeService.showSolution(problemInput, language, needTranslation); + solutionService.show(unescapeJS(solution)); + } catch (error) { + logOutput.appendLine(error.toString()); + await promptForOpenOutputChannel("Failed to fetch the top voted solution. 请查看控制台信息~", DialogType.error); + } + } + public async testapi(): Promise { + if (!statusBarService.getUser()) { + promptForSignIn(); + return; + } + try { + const twoFactor: string | undefined = await vscode.window.showInputBox({ + prompt: "测试数据", + ignoreFocusOut: true, + validateInput: (s: string): string | undefined => (s && s.trim() ? undefined : "The input must not be empty"), + }); + + // vscode.window.showErrorMessage(twoFactor || "输入错误"); + const solution: string = await executeService.getTestApi(twoFactor || ""); + const query_result = JSON.parse(solution); + console.log(query_result); + } catch (error) { + logOutput.appendLine(error.toString()); + await promptForOpenOutputChannel("Failed to fetch today question. 请查看控制台信息~", DialogType.error); + } + } - public async testapi(): Promise { - if (!statusBarService.getUser()) { - promptForSignIn(); - return; - } - try { - const twoFactor: string | undefined = await vscode.window.showInputBox({ - prompt: "测试数据", - ignoreFocusOut: true, - validateInput: (s: string): string | undefined => s && s.trim() ? undefined : "The input must not be empty", - }); - - // vscode.window.showErrorMessage(twoFactor || "输入错误"); - const solution: string = await executeService.getTestApi(twoFactor || ""); - const query_result = JSON.parse(solution); - console.log(query_result); - } catch (error) { - logOutput.appendLine(error.toString()); - await promptForOpenOutputChannel("Failed to fetch today question. 请查看控制台信息~", DialogType.error); - } + public async searchProblemByID(): Promise { + if (!statusBarService.getUser()) { + promptForSignIn(); + return; } + const choice: IQuickItemEx | undefined = await vscode.window.showQuickPick( + this.parseProblemsToPicks(this.listProblems()), + { + matchOnDetail: true, + matchOnDescription: true, + placeHolder: "Select one problem", + } + ); + if (!choice) { + return; + } + await this.showProblemInternal(choice.value); + } + public async showProblem(node?: NodeModel): Promise { + if (!node) { + return; + } + await this.showProblemInternal(node); + } + + public async pickOne(): Promise { + const problems: IProblem[] = await this.listProblems(); + let randomProblem: IProblem; + + const user_score = statusBarService.getUserContestScore(); + if (user_score > 0) { + let min_score: number = getPickOneByRankRangeMin(); + let max_score: number = getPickOneByRankRangeMax(); + let temp_problems: IProblem[] = []; + const need_min = user_score + min_score; + const need_max = user_score + max_score; + problems.forEach((element) => { + if (element.scoreData?.Rating) { + if (element.scoreData.Rating >= need_min && element.scoreData.Rating <= need_max) { + temp_problems.push(element); + } + } + }); + randomProblem = temp_problems[Math.floor(Math.random() * temp_problems.length)]; + } else { + randomProblem = problems[Math.floor(Math.random() * problems.length)]; + } + if (randomProblem) { + await this.showProblemInternal(randomProblem); + } + } - public async searchProblemByID(): Promise { - if (!statusBarService.getUser()) { - promptForSignIn(); - return; - } - const choice: IQuickItemEx | undefined = await vscode.window.showQuickPick( - this.parseProblemsToPicks(this.listProblems()), - { - matchOnDetail: true, - matchOnDescription: true, - placeHolder: "Select one problem", - }, + public async fetchProblemLanguage(): Promise { + const leetCodeConfig: vscode.WorkspaceConfiguration = vscode.workspace.getConfiguration("leetcode-problem-rating"); + let defaultLanguage: string | undefined = leetCodeConfig.get ("defaultLanguage"); + if (defaultLanguage && languages.indexOf(defaultLanguage) < 0) { + defaultLanguage = undefined; + } + const language: string | undefined = + defaultLanguage || + (await vscode.window.showQuickPick(languages, { + placeHolder: "Select the language you want to use", + ignoreFocusOut: true, + })); + // fire-and-forget default language query + (async (): Promise => { + if (language && !defaultLanguage && leetCodeConfig.get ("hint.setDefaultLanguage")) { + const choice: vscode.MessageItem | undefined = await vscode.window.showInformationMessage( + `Would you like to set '${language}' as your default language?`, + DialogOptions.yes, + DialogOptions.no, + DialogOptions.never ); - if (!choice) { - return; - } - await this.showProblemInternal(choice.value); + if (choice === DialogOptions.yes) { + leetCodeConfig.update("defaultLanguage", language, true /* UserSetting */); + } else if (choice === DialogOptions.never) { + leetCodeConfig.update("hint.setDefaultLanguage", false, true /* UserSetting */); + } + } + })(); + return language; + } + + public async selectWorkspaceFolder(): Promise { + let workspaceFolderSetting: string = getWorkspaceFolder(); + if (workspaceFolderSetting.trim() === "") { + workspaceFolderSetting = await this.determineLeetCodeFolder(); + if (workspaceFolderSetting === "") { + // User cancelled + return workspaceFolderSetting; + } } - - public async showProblem(node?: NodeModel): Promise { - if (!node) { - return; - } - await this.showProblemInternal(node); + let needAsk: boolean = true; + await fse.ensureDir(workspaceFolderSetting); + for (const folder of vscode.workspace.workspaceFolders || []) { + if (this.isSubFolder(folder.uri.fsPath, workspaceFolderSetting)) { + needAsk = false; + } } - - public async pickOne(): Promise { - const problems: IProblem[] = await this.listProblems(); - let randomProblem: IProblem; - - const user_score = statusBarService.getUserContestScore(); - if (user_score > 0) { - - let min_score: number = getPickOneByRankRangeMin(); - let max_score: number = getPickOneByRankRangeMax(); - let temp_problems: IProblem[] = []; - const need_min = user_score + min_score; - const need_max = user_score + max_score; - problems.forEach(element => { - if (element.scoreData?.Rating) { - if (element.scoreData.Rating >= need_min && element.scoreData.Rating <= need_max) { - temp_problems.push(element); - } - } - }); - randomProblem = temp_problems[Math.floor(Math.random() * temp_problems.length)]; - - } else { - randomProblem = problems[Math.floor(Math.random() * problems.length)]; - } - if (randomProblem) { - await this.showProblemInternal(randomProblem); - } + if (needAsk) { + const choice: string | undefined = await vscode.window.showQuickPick( + [ + OpenOption.justOpenFile, + OpenOption.openInCurrentWindow, + OpenOption.openInNewWindow, + OpenOption.addToWorkspace, + ], + { + placeHolder: "The LeetCode workspace folder is not opened in VS Code, would you like to open it?", + } + ); + + // Todo: generate file first + switch (choice) { + case OpenOption.justOpenFile: + return workspaceFolderSetting; + case OpenOption.openInCurrentWindow: + await vscode.commands.executeCommand("vscode.openFolder", vscode.Uri.file(workspaceFolderSetting), false); + return ""; + case OpenOption.openInNewWindow: + await vscode.commands.executeCommand("vscode.openFolder", vscode.Uri.file(workspaceFolderSetting), true); + return ""; + case OpenOption.addToWorkspace: + vscode.workspace.updateWorkspaceFolders(vscode.workspace.workspaceFolders?.length ?? 0, 0, { + uri: vscode.Uri.file(workspaceFolderSetting), + }); + break; + default: + return ""; + } } - public async fetchProblemLanguage(): Promise { - const leetCodeConfig: vscode.WorkspaceConfiguration = vscode.workspace.getConfiguration("leetcode-problem-rating"); - let defaultLanguage: string | undefined = leetCodeConfig.get ("defaultLanguage"); - if (defaultLanguage && languages.indexOf(defaultLanguage) < 0) { - defaultLanguage = undefined; - } - const language: string | undefined = defaultLanguage || await vscode.window.showQuickPick(languages, { placeHolder: "Select the language you want to use", ignoreFocusOut: true }); - // fire-and-forget default language query - (async (): Promise => { - if (language && !defaultLanguage && leetCodeConfig.get ("hint.setDefaultLanguage")) { - const choice: vscode.MessageItem | undefined = await vscode.window.showInformationMessage( - `Would you like to set '${language}' as your default language?`, - DialogOptions.yes, - DialogOptions.no, - DialogOptions.never, - ); - if (choice === DialogOptions.yes) { - leetCodeConfig.update("defaultLanguage", language, true /* UserSetting */); - } else if (choice === DialogOptions.never) { - leetCodeConfig.update("hint.setDefaultLanguage", false, true /* UserSetting */); - } - } - })(); - return language; + return systemUtils.useWsl() ? systemUtils.toWslPath(workspaceFolderSetting) : workspaceFolderSetting; + } + + public async showProblemInternal(node: IProblem): Promise { + try { + const language: string | undefined = await this.fetchProblemLanguage(); + if (!language) { + return; + } + + const leetCodeConfig: vscode.WorkspaceConfiguration = + vscode.workspace.getConfiguration("leetcode-problem-rating"); + const workspaceFolder: string = await this.selectWorkspaceFolder(); + if (!workspaceFolder) { + return; + } + + const fileFolder: string = leetCodeConfig + .get (`filePath.${language}.folder`, leetCodeConfig.get (`filePath.default.folder`, "")) + .trim(); + const fileName: string = leetCodeConfig + .get ( + `filePath.${language}.filename`, + leetCodeConfig.get (`filePath.default.filename`) || genFileName(node, language) + ) + .trim(); + + let finalPath: string = path.join(workspaceFolder, fileFolder, fileName); + + if (finalPath) { + finalPath = await this.resolveRelativePath(finalPath, node, language); + if (!finalPath) { + logOutput.appendLine("Showing problem canceled by user."); + return; + } + } + + finalPath = systemUtils.useWsl() ? await systemUtils.toWinPath(finalPath) : finalPath; + + const descriptionConfig: IDescriptionConfiguration = getDescriptionConfiguration(); + const needTranslation: boolean = isUseEndpointTranslation(); + + await executeService.showProblem(node, language, finalPath, descriptionConfig.showInComment, needTranslation); + const promises: any[] = [ + vscode.window.showTextDocument(vscode.Uri.file(finalPath), { + preview: false, + viewColumn: vscode.ViewColumn.One, + }), + promptHintMessage( + "hint.commentDescription", + 'You can config how to show the problem description through "leetcode-problem-rating.showDescription".', + "Open settings", + (): Promise => openSettingsEditor("leetcode-problem-rating.showDescription") + ), + ]; + if (descriptionConfig.showInWebview) { + promises.push(this.showDescriptionView(node)); + } + + await Promise.all(promises); + } catch (error) { + await promptForOpenOutputChannel(`${error} 请查看控制台信息~`, DialogType.error); } - - public async selectWorkspaceFolder(): Promise { - let workspaceFolderSetting: string = getWorkspaceFolder(); - if (workspaceFolderSetting.trim() === "") { - workspaceFolderSetting = await this.determineLeetCodeFolder(); - if (workspaceFolderSetting === "") { - // User cancelled - return workspaceFolderSetting; - } - } - let needAsk: boolean = true; - await fse.ensureDir(workspaceFolderSetting); - for (const folder of vscode.workspace.workspaceFolders || []) { - if (this.isSubFolder(folder.uri.fsPath, workspaceFolderSetting)) { - needAsk = false; - } - } - - if (needAsk) { - const choice: string | undefined = await vscode.window.showQuickPick( - [ - OpenOption.justOpenFile, - OpenOption.openInCurrentWindow, - OpenOption.openInNewWindow, - OpenOption.addToWorkspace, - ], - { placeHolder: "The LeetCode workspace folder is not opened in VS Code, would you like to open it?" }, - ); - - // Todo: generate file first - switch (choice) { - case OpenOption.justOpenFile: - return workspaceFolderSetting; - case OpenOption.openInCurrentWindow: - await vscode.commands.executeCommand("vscode.openFolder", vscode.Uri.file(workspaceFolderSetting), false); - return ""; - case OpenOption.openInNewWindow: - await vscode.commands.executeCommand("vscode.openFolder", vscode.Uri.file(workspaceFolderSetting), true); - return ""; - case OpenOption.addToWorkspace: - vscode.workspace.updateWorkspaceFolders(vscode.workspace.workspaceFolders?.length ?? 0, 0, { uri: vscode.Uri.file(workspaceFolderSetting) }); - break; - default: - return ""; - } - } - - return systemUtils.useWsl() ? systemUtils.toWslPath(workspaceFolderSetting) : workspaceFolderSetting; + } + + public async showDescriptionView(node: IProblem): Promise { + return this.previewProblem(node, enableSideMode()); + } + + public async previewProblem(input: IProblem | Uri, isSideMode: boolean = false): Promise { + let node: IProblem; + if (input instanceof Uri) { + const activeFilePath: string = input.fsPath; + const id: string = await getNodeIdFromFile(activeFilePath); + if (!id) { + window.showErrorMessage(`Failed to resolve the problem id from file: ${activeFilePath}.`); + return; + } + const cachedNode: IProblem | undefined = treeViewController.getNodeById(id); + if (!cachedNode) { + window.showErrorMessage(`Failed to resolve the problem with id: ${id}.`); + return; + } + node = cachedNode; + // Move the preview page aside if it's triggered from Code Lens + isSideMode = true; + } else { + node = input; } - - public async showProblemInternal(node: IProblem): Promise { - try { - const language: string | undefined = await this.fetchProblemLanguage(); - if (!language) { - return; - } - - const leetCodeConfig: vscode.WorkspaceConfiguration = vscode.workspace.getConfiguration("leetcode-problem-rating"); - const workspaceFolder: string = await this.selectWorkspaceFolder(); - if (!workspaceFolder) { - return; - } - - const fileFolder: string = leetCodeConfig - .get (`filePath.${language}.folder`, leetCodeConfig.get (`filePath.default.folder`, "")) - .trim(); - const fileName: string = leetCodeConfig - .get ( - `filePath.${language}.filename`, - leetCodeConfig.get (`filePath.default.filename`) || genFileName(node, language), - ) - .trim(); - - let finalPath: string = path.join(workspaceFolder, fileFolder, fileName); - - if (finalPath) { - finalPath = await this.resolveRelativePath(finalPath, node, language); - if (!finalPath) { - logOutput.appendLine("Showing problem canceled by user."); - return; - } - } - - finalPath = systemUtils.useWsl() ? await systemUtils.toWinPath(finalPath) : finalPath; - - const descriptionConfig: IDescriptionConfiguration = getDescriptionConfiguration(); - const needTranslation: boolean = isUseEndpointTranslation(); - - await executeService.showProblem(node, language, finalPath, descriptionConfig.showInComment, needTranslation); - const promises: any[] = [ - vscode.window.showTextDocument(vscode.Uri.file(finalPath), { preview: false, viewColumn: vscode.ViewColumn.One }), - promptHintMessage( - "hint.commentDescription", - 'You can config how to show the problem description through "leetcode-problem-rating.showDescription".', - "Open settings", - (): Promise => openSettingsEditor("leetcode-problem-rating.showDescription"), - ), - ]; - if (descriptionConfig.showInWebview) { - promises.push(this.showDescriptionView(node)); - } - - await Promise.all(promises); - } catch (error) { - await promptForOpenOutputChannel(`${error} 请查看控制台信息~`, DialogType.error); - } + const needTranslation: boolean = isUseEndpointTranslation(); + const descString: string = await executeService.getDescription(node.qid, needTranslation); + previewService.show(descString, node, isSideMode); + } + + public async searchScoreRange(): Promise { + const twoFactor: string | undefined = await vscode.window.showInputBox({ + prompt: "输入分数范围 低分-高分 例如: 1500-1600", + ignoreFocusOut: true, + validateInput: (s: string): string | undefined => (s && s.trim() ? undefined : "The input must not be empty"), + }); + + // vscode.window.showErrorMessage(twoFactor || "输入错误"); + const tt = Object.assign({}, SearchNode, { + value: twoFactor, + type: SearchSetType.ScoreRange, + time: Math.floor(Date.now() / 1000), + }); + treeViewController.insertSearchSet(tt); + await treeDataService.refresh(); + } + + public async searchContest(): Promise { + const twoFactor: string | undefined = await vscode.window.showInputBox({ + prompt: "单期数 例如: 300 或者 输入期数范围 低期数-高期数 例如: 303-306", + ignoreFocusOut: true, + validateInput: (s: string): string | undefined => (s && s.trim() ? undefined : "The input must not be empty"), + }); + + // vscode.window.showErrorMessage(twoFactor || "输入错误"); + const tt = Object.assign({}, SearchNode, { + value: twoFactor, + type: SearchSetType.Context, + time: Math.floor(Date.now() / 1000), + }); + treeViewController.insertSearchSet(tt); + await treeDataService.refresh(); + } + + public async searchUserContest(): Promise { + if (!statusBarService.getUser()) { + promptForSignIn(); + return; } - - public async showDescriptionView(node: IProblem): Promise { - return this.previewProblem(node, enableSideMode()); + try { + const needTranslation: boolean = isUseEndpointTranslation(); + const solution: string = await executeService.getUserContest(needTranslation, statusBarService.getUser() || ""); + const query_result = JSON.parse(solution); + const tt: userContestRanKingBase = Object.assign({}, userContestRankingObj, query_result.userContestRanking); + eventService.emit("searchUserContest", tt); + } catch (error) { + logOutput.appendLine(error.toString()); + await promptForOpenOutputChannel("Failed to fetch today question. 请查看控制台信息~", DialogType.error); } - - public async previewProblem(input: IProblem | Uri, isSideMode: boolean = false): Promise { - let node: IProblem; - if (input instanceof Uri) { - const activeFilePath: string = input.fsPath; - const id: string = await getNodeIdFromFile(activeFilePath); - if (!id) { - window.showErrorMessage(`Failed to resolve the problem id from file: ${activeFilePath}.`); - return; - } - const cachedNode: IProblem | undefined = treeViewController.getNodeById(id); - if (!cachedNode) { - window.showErrorMessage(`Failed to resolve the problem with id: ${id}.`); - return; - } - node = cachedNode; - // Move the preview page aside if it's triggered from Code Lens - isSideMode = true; - } else { - node = input; - } - const needTranslation: boolean = isUseEndpointTranslation(); - const descString: string = await executeService.getDescription(node.qid, needTranslation); - previewService.show(descString, node, isSideMode); + } + public async searchToday(): Promise { + if (!statusBarService.getUser()) { + promptForSignIn(); + return; } - - - public async searchScoreRange(): Promise { - const twoFactor: string | undefined = await vscode.window.showInputBox({ - prompt: "输入分数范围 低分-高分 例如: 1500-1600", - ignoreFocusOut: true, - validateInput: (s: string): string | undefined => s && s.trim() ? undefined : "The input must not be empty", - }); - - // vscode.window.showErrorMessage(twoFactor || "输入错误"); + try { + const needTranslation: boolean = isUseEndpointTranslation(); + const solution: string = await executeService.getTodayQuestion(needTranslation); + const query_result = JSON.parse(solution); + // const titleSlug: string = query_result.titleSlug + // const questionId: string = query_result.questionId + const fid: string = query_result.fid; + if (fid) { const tt = Object.assign({}, SearchNode, { - value: twoFactor, - type: SearchSetType.ScoreRange, - time: Math.floor(Date.now() / 1000) + value: fid, + type: SearchSetType.Day, + time: Math.floor(Date.now() / 1000), + todayData: query_result, }); treeViewController.insertSearchSet(tt); await treeDataService.refresh(); + } + } catch (error) { + logOutput.appendLine(error.toString()); + await promptForOpenOutputChannel("Failed to fetch today question. 请查看控制台信息~", DialogType.error); } - - public async searchContest(): Promise { - const twoFactor: string | undefined = await vscode.window.showInputBox({ - prompt: "单期数 例如: 300 或者 输入期数范围 低期数-高期数 例如: 303-306", - ignoreFocusOut: true, - validateInput: (s: string): string | undefined => s && s.trim() ? undefined : "The input must not be empty", - }); - - // vscode.window.showErrorMessage(twoFactor || "输入错误"); - const tt = Object.assign({}, SearchNode, { - value: twoFactor, - type: SearchSetType.Context, - time: Math.floor(Date.now() / 1000) - }); - treeViewController.insertSearchSet(tt); - await treeDataService.refresh(); + } + + public async parseProblemsToPicks(p: Promise ): Promise >> { + return new Promise(async (resolve: (res: Array >) => void): Promise => { + const picks: Array > = (await p).map((problem: IProblem) => + Object.assign( + {}, + { + label: `${this.parseProblemDecorator(problem.state, problem.locked)}${problem.id}.${problem.name}`, + description: `QID:${problem.qid}`, + detail: + ((problem.scoreData?.score || "0") > "0" ? "score: " + problem.scoreData?.score + " , " : "") + + `AC rate: ${problem.passRate}, Difficulty: ${problem.difficulty}`, + value: problem, + } + ) + ); + resolve(picks); + }); + } + + public parseProblemDecorator(state: ProblemState, locked: boolean): string { + switch (state) { + case ProblemState.AC: + return "$(check) "; + case ProblemState.NotAC: + return "$(x) "; + default: + return locked ? "$(lock) " : ""; } + } - - - public async searchUserContest(): Promise { - if (!statusBarService.getUser()) { - promptForSignIn(); - return; - } - try { - const needTranslation: boolean = isUseEndpointTranslation(); - const solution: string = await executeService.getUserContest(needTranslation, statusBarService.getUser() || ""); - const query_result = JSON.parse(solution); - const tt: userContestRanKingBase = Object.assign({}, userContestRankingObj, query_result.userContestRanking); - eventService.emit("searchUserContest", tt); - } catch (error) { - logOutput.appendLine(error.toString()); - await promptForOpenOutputChannel("Failed to fetch today question. 请查看控制台信息~", DialogType.error); - } + public async resolveRelativePath(relativePath: string, node: IProblem, selectedLanguage: string): Promise { + let tag: string = ""; + if (/\$\{ tag \} /i.test(relativePath)) { + tag = (await this.resolveTagForProblem(node)) || ""; } - public async searchToday(): Promise { - if (!statusBarService.getUser()) { - promptForSignIn(); - return; - } - try { - const needTranslation: boolean = isUseEndpointTranslation(); - const solution: string = await executeService.getTodayQuestion(needTranslation); - const query_result = JSON.parse(solution); - // const titleSlug: string = query_result.titleSlug - // const questionId: string = query_result.questionId - const fid: string = query_result.fid; - if (fid) { - const tt = Object.assign({}, SearchNode, { - value: fid, - type: SearchSetType.Day, - time: Math.floor(Date.now() / 1000), - todayData: query_result, - }); - treeViewController.insertSearchSet(tt); - await treeDataService.refresh(); - } - } catch (error) { - logOutput.appendLine(error.toString()); - await promptForOpenOutputChannel("Failed to fetch today question. 请查看控制台信息~", DialogType.error); - } + let company: string = ""; + if (/\$\{company\}/i.test(relativePath)) { + company = (await this.resolveCompanyForProblem(node)) || ""; } - - - - public async parseProblemsToPicks(p: Promise ): Promise >> { - return new Promise(async (resolve: (res: Array >) => void): Promise => { - const picks: Array > = (await p).map((problem: IProblem) => Object.assign({}, { - label: `${this.parseProblemDecorator(problem.state, problem.locked)}${problem.id}.${problem.name}`, - description: `QID:${problem.qid}`, - detail: ((problem.scoreData?.score || "0") > "0" ? ("score: " + problem.scoreData?.score + " , ") : "") + `AC rate: ${problem.passRate}, Difficulty: ${problem.difficulty}`, - value: problem, - })); - resolve(picks); - }); + let errorMsg: string; + return relativePath.replace(/\$\{(.*?)\}/g, (_substring: string, ...args: string[]) => { + const placeholder: string = args[0].toLowerCase().trim(); + switch (placeholder) { + case "id": + return node.id; + case "name": + return node.name; + case "camelcasename": + return lodash.camelCase(node.name); + case "pascalcasename": + return lodash.upperFirst(lodash.camelCase(node.name)); + case "kebabcasename": + case "kebab-case-name": + return lodash.kebabCase(node.name); + case "snakecasename": + case "snake_case_name": + return lodash.snakeCase(node.name); + case "ext": + return genFileExt(selectedLanguage); + case "language": + return selectedLanguage; + case "difficulty": + return node.difficulty.toLocaleLowerCase(); + case "tag": + return tag; + case "company": + return company; + default: + errorMsg = `The config '${placeholder}' is not supported.`; + logOutput.appendLine(errorMsg); + throw new Error(errorMsg); + } + }); + } + + public async resolveTagForProblem(problem: IProblem): Promise { + if (problem.tags.length === 1) { + return problem.tags[0]; } - - public parseProblemDecorator(state: ProblemState, locked: boolean): string { - switch (state) { - case ProblemState.AC: - return "$(check) "; - case ProblemState.NotAC: - return "$(x) "; - default: - return locked ? "$(lock) " : ""; - } + return await vscode.window.showQuickPick(problem.tags, { + matchOnDetail: true, + placeHolder: "Multiple tags available, please select one", + ignoreFocusOut: true, + }); + } + + public async resolveCompanyForProblem(problem: IProblem): Promise { + if (problem.companies.length === 1) { + return problem.companies[0]; } - - public async resolveRelativePath(relativePath: string, node: IProblem, selectedLanguage: string): Promise { - let tag: string = ""; - if (/\$\{ tag \} /i.test(relativePath)) { - tag = (await this.resolveTagForProblem(node)) || ""; - } - - let company: string = ""; - if (/\$\{company\}/i.test(relativePath)) { - company = (await this.resolveCompanyForProblem(node)) || ""; - } - - let errorMsg: string; - return relativePath.replace(/\$\{(.*?)\}/g, (_substring: string, ...args: string[]) => { - const placeholder: string = args[0].toLowerCase().trim(); - switch (placeholder) { - case "id": - return node.id; - case "name": - return node.name; - case "camelcasename": - return lodash.camelCase(node.name); - case "pascalcasename": - return lodash.upperFirst(lodash.camelCase(node.name)); - case "kebabcasename": - case "kebab-case-name": - return lodash.kebabCase(node.name); - case "snakecasename": - case "snake_case_name": - return lodash.snakeCase(node.name); - case "ext": - return genFileExt(selectedLanguage); - case "language": - return selectedLanguage; - case "difficulty": - return node.difficulty.toLocaleLowerCase(); - case "tag": - return tag; - case "company": - return company; - default: - errorMsg = `The config '${placeholder}' is not supported.`; - logOutput.appendLine(errorMsg); - throw new Error(errorMsg); + return await vscode.window.showQuickPick(problem.companies, { + matchOnDetail: true, + placeHolder: "Multiple tags available, please select one", + ignoreFocusOut: true, + }); + } + + public insertSearchSet(tt: ISearchSet) { + this.searchSet.set(tt.value, tt); + } + public clearUserScore() { + this.waitUserContest = false; + this.waitTodayQuestion = false; + this.searchSet = new Map (); + } + + public checkSubmit(e: ISubmitEvent) { + if (e.sub_type == "submit" && e.accepted) { + const day_start = new Date(new Date().setHours(0, 0, 0, 0)).getTime() / 1000; //获取当天零点的时间 + const day_end = new Date(new Date().setHours(0, 0, 0, 0) + 24 * 60 * 60 * 1000 - 1).getTime() / 1000; //获取当天23:59:59的时间 + let need_get_today: boolean = false; + this.searchSet.forEach((element) => { + if (element.type == SearchSetType.Day) { + if (day_start <= element.time && element.time <= day_end) { + if (e.fid == element.value) { + need_get_today = true; } - }); - } - - public async resolveTagForProblem(problem: IProblem): Promise { - if (problem.tags.length === 1) { - return problem.tags[0]; + } } - return await vscode.window.showQuickPick( - problem.tags, - { - matchOnDetail: true, - placeHolder: "Multiple tags available, please select one", - ignoreFocusOut: true, - }, - ); + }); + if (need_get_today) { + this.searchToday(); + } } + } - public async resolveCompanyForProblem(problem: IProblem): Promise { - if (problem.companies.length === 1) { - return problem.companies[0]; - } - return await vscode.window.showQuickPick(problem.companies, { - matchOnDetail: true, - placeHolder: "Multiple tags available, please select one", - ignoreFocusOut: true, - }); + public async refreshCheck(): Promise { + if (!statusBarService.getUser()) { + return; } - - - public insertSearchSet(tt: ISearchSet) { - this.searchSet.set(tt.value, tt); - } - public clearUserScore() { - this.waitUserContest = false; - this.waitTodayQuestion = false; - this.searchSet = new Map (); - } - - public checkSubmit(e: ISubmitEvent) { - if (e.sub_type == "submit" && e.accepted) { - const day_start = new Date(new Date().setHours(0, 0, 0, 0)).getTime() / 1000; //获取当天零点的时间 - const day_end = new Date(new Date().setHours(0, 0, 0, 0) + 24 * 60 * 60 * 1000 - 1).getTime() / 1000; //获取当天23:59:59的时间 - let need_get_today: boolean = false; - this.searchSet.forEach(element => { - if (element.type == SearchSetType.Day) { - if (day_start <= element.time && element.time <= day_end) { - if (e.fid == element.value) { - need_get_today = true; - } - } - } - }); - if (need_get_today) { - this.searchToday(); - } - } - } - - public async refreshCheck(): Promise { - if (!statusBarService.getUser()) { - return; - } - const day_start = new Date(new Date().setHours(0, 0, 0, 0)).getTime() / 1000; //获取当天零点的时间 - const day_end = new Date(new Date().setHours(0, 0, 0, 0) + 24 * 60 * 60 * 1000 - 1).getTime() / 1000; //获取当天23:59:59的时间 - let need_get_today: boolean = true; - this.searchSet.forEach(element => { - if (element.type == SearchSetType.Day) { - if (day_start <= element.time && element.time <= day_end) { - need_get_today = false; - } else { - this.waitTodayQuestion = false; - } - } - }); - if (need_get_today && !this.waitTodayQuestion) { - this.waitTodayQuestion = true; - await this.searchToday(); - } - let user_score = statusBarService.getUserContestScore(); - if (!user_score && !this.waitUserContest) { - this.waitUserContest = true; - await this.searchUserContest(); + const day_start = new Date(new Date().setHours(0, 0, 0, 0)).getTime() / 1000; //获取当天零点的时间 + const day_end = new Date(new Date().setHours(0, 0, 0, 0) + 24 * 60 * 60 * 1000 - 1).getTime() / 1000; //获取当天23:59:59的时间 + let need_get_today: boolean = true; + this.searchSet.forEach((element) => { + if (element.type == SearchSetType.Day) { + if (day_start <= element.time && element.time <= day_end) { + need_get_today = false; + } else { + this.waitTodayQuestion = false; } + } + }); + if (need_get_today && !this.waitTodayQuestion) { + this.waitTodayQuestion = true; + await this.searchToday(); } - - public async refreshCache(): Promise { - const temp_searchSet: Map = this.searchSet; - const temp_waitTodayQuestion: boolean = this.waitTodayQuestion; - const temp_waitUserContest: boolean = this.waitUserContest; - this.dispose(); - let user_score = statusBarService.getUserContestScore(); - for (const problem of await this.listProblems()) { - this.explorerNodeMap.set(problem.id, new NodeModel(problem, true, user_score)); - for (const company of problem.companies) { - this.companySet.add(company); - } - for (const tag of problem.tags) { - this.tagSet.add(tag); - } - } - this.searchSet = temp_searchSet; - this.waitTodayQuestion = temp_waitTodayQuestion; - this.waitUserContest = temp_waitUserContest; - } - - public getRootNodes(): NodeModel[] { - let user_score = statusBarService.getUserContestScore(); - const baseNode: NodeModel[] = [ - new NodeModel(Object.assign({}, defaultProblem, { - id: Category.All, - name: Category.All, - rootNodeSortId: RootNodeSort.All, - }), false), - new NodeModel(Object.assign({}, defaultProblem, { - id: Category.Difficulty, - name: Category.Difficulty, - rootNodeSortId: RootNodeSort.Difficulty, - }), false), - new NodeModel(Object.assign({}, defaultProblem, { - id: Category.Tag, - name: Category.Tag, - rootNodeSortId: RootNodeSort.Tag, - }), false), - // new NodeModel(Object.assign({}, defaultProblem, { - // id: Category.Company, - // name: Category.Company, - // rootNodeSortId: RootNodeSort.Company, - // }), false), - new NodeModel(Object.assign({}, defaultProblem, { - id: Category.Favorite, - name: Category.Favorite, - rootNodeSortId: RootNodeSort.Favorite, - }), false), - new NodeModel(Object.assign({}, defaultProblem, { - id: Category.Score, - name: Category.Score, - rootNodeSortId: RootNodeSort.Score, - }), false, user_score), - new NodeModel(Object.assign({}, defaultProblem, { - id: Category.Choice, - name: Category.Choice, - rootNodeSortId: RootNodeSort.Choice, - }), false), - ]; - this.searchSet.forEach(element => { - if (element.type == SearchSetType.Day) { - const curDate = new Date(element.time * 1000); - baseNode.push(new NodeModel(Object.assign({}, defaultProblem, { - id: element.type, - name: "[" + (curDate.getFullYear()) + "-" + (curDate.getMonth() + 1) + "-" + (curDate.getDate()) + "]" + SearchSetTypeName[SearchSetType.Day], - input: element.value, - isSearchResult: true, - rootNodeSortId: RootNodeSort[element.type], - todayData: element.todayData - }), false)); - } else { - baseNode.push(new NodeModel(Object.assign({}, defaultProblem, { - id: element.type, - name: SearchSetTypeName[element.type] + element.value, - input: element.value, - isSearchResult: true, - rootNodeSortId: RootNodeSort[element.type], - }), false)); - } - }); - baseNode.sort(function (a: NodeModel, b: NodeModel): number { - if (a.rootNodeSortId < b.rootNodeSortId) { - return -1; - } else if (a.rootNodeSortId > b.rootNodeSortId) { - return 1; - } - return 0; - }); - return baseNode; - } - - public getScoreRangeNodes(rank_range: string): NodeModel[] { - const sorceNode: NodeModel[] = []; - const rank_r: Array = rank_range.split("-"); - let rank_a = Number(rank_r[0]); - let rank_b = Number(rank_r[1]); - if (rank_a > 0 && rank_b > 0) { - if (rank_a > rank_b) { - const rank_c: number = rank_a; - rank_a = rank_b; - rank_b = rank_c; - } - - this.explorerNodeMap.forEach(element => { - if (!this.canShow(element)) { - return; - } - if (rank_a <= Number(element.score) && Number(element.score) <= rank_b) { - sorceNode.push(element); - } - }); - } - return this.applySortingStrategy(sorceNode); + let user_score = statusBarService.getUserContestScore(); + if (!user_score && !this.waitUserContest) { + this.waitUserContest = true; + await this.searchUserContest(); } - - public canShow(element: NodeModel) { - if (isHideSolvedProblem() && element.state === ProblemState.AC) { - return false; - } - if (isHideScoreProblem(element, element.user_score)) { - return false; - } - return true; - } - - public getContextNodes(rank_range: string): NodeModel[] { - const sorceNode: NodeModel[] = []; - const rank_r: Array = rank_range.split("-"); - let rank_a = Number(rank_r[0]); - let rank_b = Number(rank_r[1]); - if (rank_a > 0) { - this.explorerNodeMap.forEach(element => { - if (!this.canShow(element)) { - return; - } - const slu = element.ContestSlug; - const slu_arr: Array = slu.split("-"); - const slu_id = Number(slu_arr[slu_arr.length - 1]); - if (rank_b > 0 && rank_a <= slu_id && slu_id <= rank_b) { - sorceNode.push(element); - } else if (rank_a == slu_id) { - sorceNode.push(element); - } - }); - } - return this.applySortingStrategy(sorceNode); - } - public getDayNodes(element: NodeModel | undefined): NodeModel[] { - const rank_range: string = element?.input || ""; - const sorceNode: NodeModel[] = []; - if (rank_range) { - this.explorerNodeMap.forEach(new_node => { - if (new_node.id == rank_range) { - new_node.todayData = element?.todayData; - sorceNode.push(new_node); - } - }); - } - return this.applySortingStrategy(sorceNode); + } + + public async refreshCache(): Promise { + const temp_searchSet: Map = this.searchSet; + const temp_waitTodayQuestion: boolean = this.waitTodayQuestion; + const temp_waitUserContest: boolean = this.waitUserContest; + this.dispose(); + let user_score = statusBarService.getUserContestScore(); + for (const problem of await this.listProblems()) { + this.explorerNodeMap.set(problem.id, new NodeModel(problem, true, user_score)); + for (const company of problem.companies) { + this.companySet.add(company); + } + for (const tag of problem.tags) { + this.tagSet.add(tag); + } } - - public getAllNodes(): NodeModel[] { - return this.applySortingStrategy( - Array.from(this.explorerNodeMap.values()).filter(p => this.canShow(p)), + this.searchSet = temp_searchSet; + this.waitTodayQuestion = temp_waitTodayQuestion; + this.waitUserContest = temp_waitUserContest; + } + + public getRootNodes(): NodeModel[] { + let user_score = statusBarService.getUserContestScore(); + const baseNode: NodeModel[] = [ + new NodeModel( + Object.assign({}, defaultProblem, { + id: Category.All, + name: Category.All, + rootNodeSortId: RootNodeSort.All, + }), + false + ), + new NodeModel( + Object.assign({}, defaultProblem, { + id: Category.Difficulty, + name: Category.Difficulty, + rootNodeSortId: RootNodeSort.Difficulty, + }), + false + ), + new NodeModel( + Object.assign({}, defaultProblem, { + id: Category.Tag, + name: Category.Tag, + rootNodeSortId: RootNodeSort.Tag, + }), + false + ), + // new NodeModel(Object.assign({}, defaultProblem, { + // id: Category.Company, + // name: Category.Company, + // rootNodeSortId: RootNodeSort.Company, + // }), false), + new NodeModel( + Object.assign({}, defaultProblem, { + id: Category.Favorite, + name: Category.Favorite, + rootNodeSortId: RootNodeSort.Favorite, + }), + false + ), + new NodeModel( + Object.assign({}, defaultProblem, { + id: Category.Score, + name: Category.Score, + rootNodeSortId: RootNodeSort.Score, + }), + false, + user_score + ), + new NodeModel( + Object.assign({}, defaultProblem, { + id: Category.Choice, + name: Category.Choice, + rootNodeSortId: RootNodeSort.Choice, + }), + false + ), + ]; + this.searchSet.forEach((element) => { + if (element.type == SearchSetType.Day) { + const curDate = new Date(element.time * 1000); + baseNode.push( + new NodeModel( + Object.assign({}, defaultProblem, { + id: element.type, + name: + "[" + + curDate.getFullYear() + + "-" + + (curDate.getMonth() + 1) + + "-" + + curDate.getDate() + + "]" + + SearchSetTypeName[SearchSetType.Day], + input: element.value, + isSearchResult: true, + rootNodeSortId: RootNodeSort[element.type], + todayData: element.todayData, + }), + false + ) ); + } else { + baseNode.push( + new NodeModel( + Object.assign({}, defaultProblem, { + id: element.type, + name: SearchSetTypeName[element.type] + element.value, + input: element.value, + isSearchResult: true, + rootNodeSortId: RootNodeSort[element.type], + }), + false + ) + ); + } + }); + baseNode.sort(function (a: NodeModel, b: NodeModel): number { + if (a.rootNodeSortId < b.rootNodeSortId) { + return -1; + } else if (a.rootNodeSortId > b.rootNodeSortId) { + return 1; + } + return 0; + }); + return baseNode; + } + + public getScoreRangeNodes(rank_range: string): NodeModel[] { + const sorceNode: NodeModel[] = []; + const rank_r: Array = rank_range.split("-"); + let rank_a = Number(rank_r[0]); + let rank_b = Number(rank_r[1]); + if (rank_a > 0 && rank_b > 0) { + if (rank_a > rank_b) { + const rank_c: number = rank_a; + rank_a = rank_b; + rank_b = rank_c; + } + + this.explorerNodeMap.forEach((element) => { + if (!this.canShow(element)) { + return; + } + if (rank_a <= Number(element.score) && Number(element.score) <= rank_b) { + sorceNode.push(element); + } + }); } + return this.applySortingStrategy(sorceNode); + } - public getAllDifficultyNodes(): NodeModel[] { - const res: NodeModel[] = []; + public canShow(element: NodeModel) { + if (isHideSolvedProblem() && element.state === ProblemState.AC) { + return false; + } + if (isHideScoreProblem(element, element.user_score)) { + return false; + } + return true; + } + + public getContextNodes(rank_range: string): NodeModel[] { + const sorceNode: NodeModel[] = []; + const rank_r: Array = rank_range.split("-"); + let rank_a = Number(rank_r[0]); + let rank_b = Number(rank_r[1]); + if (rank_a > 0) { + this.explorerNodeMap.forEach((element) => { + if (!this.canShow(element)) { + return; + } + const slu = element.ContestSlug; + const slu_arr: Array = slu.split("-"); + const slu_id = Number(slu_arr[slu_arr.length - 1]); + if (rank_b > 0 && rank_a <= slu_id && slu_id <= rank_b) { + sorceNode.push(element); + } else if (rank_a == slu_id) { + sorceNode.push(element); + } + }); + } + return this.applySortingStrategy(sorceNode); + } + public getDayNodes(element: NodeModel | undefined): NodeModel[] { + const rank_range: string = element?.input || ""; + const sorceNode: NodeModel[] = []; + if (rank_range) { + this.explorerNodeMap.forEach((new_node) => { + if (new_node.id == rank_range) { + new_node.todayData = element?.todayData; + sorceNode.push(new_node); + } + }); + } + return this.applySortingStrategy(sorceNode); + } + + public getAllNodes(): NodeModel[] { + return this.applySortingStrategy(Array.from(this.explorerNodeMap.values()).filter((p) => this.canShow(p))); + } + + public getAllDifficultyNodes(): NodeModel[] { + const res: NodeModel[] = []; + res.push( + new NodeModel( + Object.assign({}, defaultProblem, { + id: `${Category.Difficulty}.Easy`, + name: "Easy", + }), + false + ), + new NodeModel( + Object.assign({}, defaultProblem, { + id: `${Category.Difficulty}.Medium`, + name: "Medium", + }), + false + ), + new NodeModel( + Object.assign({}, defaultProblem, { + id: `${Category.Difficulty}.Hard`, + name: "Hard", + }), + false + ) + ); + this.sortSubCategoryNodes(res, Category.Difficulty); + return res; + } + + public getAllScoreNodes(user_score: number): NodeModel[] { + const res: NodeModel[] = []; + const score_array: Array = [ + "3300", + "3200", + "3100", + "3000", + "2900", + "2800", + "2700", + "2600", + "2500", + "2400", + "2300", + "2200", + "2100", + "2000", + "1900", + "1800", + "1700", + "1600", + "1500", + "1400", + "1300", + "1200", + "1100", + ]; + score_array.forEach((element) => { + const temp_num = Number(element); + const diff = Math.abs(temp_num - user_score); + if (diff <= 200) { res.push( - new NodeModel(Object.assign({}, defaultProblem, { - id: `${Category.Difficulty}.Easy`, - name: "Easy", - }), false), - new NodeModel(Object.assign({}, defaultProblem, { - id: `${Category.Difficulty}.Medium`, - name: "Medium", - }), false), - new NodeModel(Object.assign({}, defaultProblem, { - id: `${Category.Difficulty}.Hard`, - name: "Hard", - }), false), + new NodeModel( + Object.assign({}, defaultProblem, { + id: `${Category.Score}.${element}`, + name: `${element}`, + }), + false, + user_score + ) ); - this.sortSubCategoryNodes(res, Category.Difficulty); - return res; - } - - public getAllScoreNodes(user_score: number): NodeModel[] { - const res: NodeModel[] = []; - const score_array: Array = ["3300", "3200", "3100", "3000", "2900", "2800", "2700", "2600", "2500", "2400", "2300", "2200", "2100", "2000", "1900", "1800", "1700", "1600", "1500", "1400", "1300", "1200", "1100"]; - score_array.forEach(element => { - const temp_num = Number(element); - const diff = Math.abs(temp_num - user_score); - if (diff <= 200) { - res.push(new NodeModel(Object.assign({}, defaultProblem, { - id: `${Category.Score}.${element}`, - name: `${element}`, - }), false, user_score)); - } - }); - - this.sortSubCategoryNodes(res, Category.Score); - return res; + } + }); + + this.sortSubCategoryNodes(res, Category.Score); + return res; + } + + public getAllChoiceNodes(): NodeModel[] { + const res: NodeModel[] = []; + + const all_choice = treeDataService.getChoiceData(); + all_choice.forEach((element) => { + res.push( + new NodeModel( + Object.assign({}, defaultProblem, { + id: `${Category.Choice}.${element.id}`, + name: `${element.name}`, + }), + false + ) + ); + }); + this.sortSubCategoryNodes(res, Category.Choice); + return res; + } + + public getAllCompanyNodes(): NodeModel[] { + const res: NodeModel[] = []; + for (const company of this.companySet.values()) { + res.push( + new NodeModel( + Object.assign({}, defaultProblem, { + id: `${Category.Company}.${company}`, + name: lodash.startCase(company), + }), + false + ) + ); } - - public getAllChoiceNodes(): NodeModel[] { - const res: NodeModel[] = []; - - const all_choice = treeDataService.getChoiceData(); - all_choice.forEach(element => { - res.push(new NodeModel(Object.assign({}, defaultProblem, { - id: `${Category.Choice}.${element.id}`, - name: `${element.name}`, - }), false)); - }); - this.sortSubCategoryNodes(res, Category.Choice); - return res; + this.sortSubCategoryNodes(res, Category.Company); + return res; + } + + public getAllTagNodes(): NodeModel[] { + const res: NodeModel[] = []; + for (const tag of this.tagSet.values()) { + res.push( + new NodeModel( + Object.assign({}, defaultProblem, { + id: `${Category.Tag}.${tag}`, + name: lodash.startCase(tag), + }), + false + ) + ); } - - public getAllCompanyNodes(): NodeModel[] { - const res: NodeModel[] = []; - for (const company of this.companySet.values()) { - res.push(new NodeModel(Object.assign({}, defaultProblem, { - id: `${Category.Company}.${company}`, - name: lodash.startCase(company), - }), false)); - } - this.sortSubCategoryNodes(res, Category.Company); - return res; + this.sortSubCategoryNodes(res, Category.Tag); + return res; + } + + public getNodeById(id: string): NodeModel | undefined { + return this.explorerNodeMap.get(id); + } + + public getFavoriteNodes(): NodeModel[] { + const res: NodeModel[] = []; + for (const node of this.explorerNodeMap.values()) { + if (!this.canShow(node)) { + continue; + } + if (node.isFavorite) { + res.push(node); + } } - - public getAllTagNodes(): NodeModel[] { - const res: NodeModel[] = []; - for (const tag of this.tagSet.values()) { - res.push(new NodeModel(Object.assign({}, defaultProblem, { - id: `${Category.Tag}.${tag}`, - name: lodash.startCase(tag), - }), false)); - } - this.sortSubCategoryNodes(res, Category.Tag); - return res; + return this.applySortingStrategy(res); + } + + public getChildrenNodesById(id: string): NodeModel[] { + // The sub-category node's id is named as {Category.SubName} + const metaInfo: string[] = id.split("."); + const res: NodeModel[] = []; + + const choiceQuestionId: Map = new Map (); + if (metaInfo[0] == Category.Choice) { + const all_choice = treeDataService.getChoiceData(); + all_choice.forEach((element) => { + if (element.id == metaInfo[1]) { + element.questions.forEach((kk) => { + choiceQuestionId[kk] = true; + }); + return; + } + }); } - public getNodeById(id: string): NodeModel | undefined { - return this.explorerNodeMap.get(id); - } - - public getFavoriteNodes(): NodeModel[] { - const res: NodeModel[] = []; - for (const node of this.explorerNodeMap.values()) { - if (!this.canShow(node)) { - continue; - } - if (node.isFavorite) { - res.push(node); - } - } - return this.applySortingStrategy(res); - } - - public getChildrenNodesById(id: string): NodeModel[] { - // The sub-category node's id is named as {Category.SubName} - const metaInfo: string[] = id.split("."); - const res: NodeModel[] = []; - - const choiceQuestionId: Map = new Map (); - if (metaInfo[0] == Category.Choice) { - const all_choice = treeDataService.getChoiceData(); - all_choice.forEach(element => { - if (element.id == metaInfo[1]) { - element.questions.forEach(kk => { - choiceQuestionId[kk] = true; - }); - return; - } - }); - } - - for (const node of this.explorerNodeMap.values()) { - if (!this.canShow(node)) { - continue; + for (const node of this.explorerNodeMap.values()) { + if (!this.canShow(node)) { + continue; + } + switch (metaInfo[0]) { + case Category.Company: + if (node.companies.indexOf(metaInfo[1]) >= 0) { + res.push(node); + } + break; + case Category.Difficulty: + if (node.difficulty === metaInfo[1]) { + res.push(node); + } + break; + case Category.Tag: + if (node.tags.indexOf(metaInfo[1]) >= 0) { + res.push(node); + } + break; + case Category.Score: + if (node.score > "0") { + const check_rank = toNumber(metaInfo[1]); + const node_rank = toNumber(node.score); + if (check_rank <= node_rank && node_rank < check_rank + 100) { + res.push(node); } - switch (metaInfo[0]) { - case Category.Company: - if (node.companies.indexOf(metaInfo[1]) >= 0) { - res.push(node); - } - break; - case Category.Difficulty: - if (node.difficulty === metaInfo[1]) { - res.push(node); - } - break; - case Category.Tag: - if (node.tags.indexOf(metaInfo[1]) >= 0) { - res.push(node); - } - break; - case Category.Score: - if (node.score > "0") { - const check_rank = toNumber(metaInfo[1]); - const node_rank = toNumber(node.score); - if (check_rank <= node_rank && node_rank < check_rank + 100) { - res.push(node); - } - } - break; - case Category.Choice: - if (choiceQuestionId[Number(node.qid)]) { - res.push(node); - } + } + break; + case Category.Choice: + if (choiceQuestionId[Number(node.qid)]) { + res.push(node); + } + } + } + return this.applySortingStrategy(res); + } + + public dispose(): void { + this.explorerNodeMap.clear(); + this.companySet.clear(); + this.tagSet.clear(); + } + + private sortSubCategoryNodes(subCategoryNodes: NodeModel[], category: Category): void { + switch (category) { + case Category.Difficulty: + subCategoryNodes.sort((a: NodeModel, b: NodeModel): number => { + function getValue(input: NodeModel): number { + switch (input.name.toLowerCase()) { + case "easy": + return 1; + case "medium": + return 2; + case "hard": + return 3; + default: + return Number.MAX_SAFE_INTEGER; } - } - return this.applySortingStrategy(res); - } - - public dispose(): void { - this.explorerNodeMap.clear(); - this.companySet.clear(); - this.tagSet.clear(); - } - - private sortSubCategoryNodes(subCategoryNodes: NodeModel[], category: Category): void { - switch (category) { - case Category.Difficulty: - subCategoryNodes.sort((a: NodeModel, b: NodeModel): number => { - function getValue(input: NodeModel): number { - switch (input.name.toLowerCase()) { - case "easy": - return 1; - case "medium": - return 2; - case "hard": - return 3; - default: - return Number.MAX_SAFE_INTEGER; - } - } - return getValue(a) - getValue(b); - }); - break; - case Category.Tag: - case Category.Company: - subCategoryNodes.sort((a: NodeModel, b: NodeModel): number => { - if (a.name === "Unknown") { - return 1; - } else if (b.name === "Unknown") { - return -1; - } else { - return Number(a.name > b.name) - Number(a.name < b.name); - } - }); - break; - default: - break; - } + } + return getValue(a) - getValue(b); + }); + break; + case Category.Tag: + case Category.Company: + subCategoryNodes.sort((a: NodeModel, b: NodeModel): number => { + if (a.name === "Unknown") { + return 1; + } else if (b.name === "Unknown") { + return -1; + } else { + return Number(a.name > b.name) - Number(a.name < b.name); + } + }); + break; + default: + break; } - - private applySortingStrategy(nodes: NodeModel[]): NodeModel[] { - const strategy: SortingStrategy = getSortingStrategy(); - switch (strategy) { - case SortingStrategy.AcceptanceRateAsc: return nodes.sort((x: NodeModel, y: NodeModel) => Number(x.acceptanceRate) - Number(y.acceptanceRate)); - case SortingStrategy.AcceptanceRateDesc: return nodes.sort((x: NodeModel, y: NodeModel) => Number(y.acceptanceRate) - Number(x.acceptanceRate)); - case SortingStrategy.ScoreAsc: return nodes.sort((x: NodeModel, y: NodeModel) => Number(x.score) - Number(y.score)); - case SortingStrategy.ScoreDesc: return nodes.sort((x: NodeModel, y: NodeModel) => Number(y.score) - Number(x.score)); - case SortingStrategy.IDDesc: return nodes.sort((x: NodeModel, y: NodeModel) => Number(y.id) - Number(x.id)); - default: return nodes; - } + } + + private applySortingStrategy(nodes: NodeModel[]): NodeModel[] { + const strategy: SortingStrategy = getSortingStrategy(); + switch (strategy) { + case SortingStrategy.AcceptanceRateAsc: + return nodes.sort((x: NodeModel, y: NodeModel) => Number(x.acceptanceRate) - Number(y.acceptanceRate)); + case SortingStrategy.AcceptanceRateDesc: + return nodes.sort((x: NodeModel, y: NodeModel) => Number(y.acceptanceRate) - Number(x.acceptanceRate)); + case SortingStrategy.ScoreAsc: + return nodes.sort((x: NodeModel, y: NodeModel) => Number(x.score) - Number(y.score)); + case SortingStrategy.ScoreDesc: + return nodes.sort((x: NodeModel, y: NodeModel) => Number(y.score) - Number(x.score)); + case SortingStrategy.IDDesc: + return nodes.sort((x: NodeModel, y: NodeModel) => Number(y.id) - Number(x.id)); + default: + return nodes; } + } } export const treeViewController: TreeViewController = new TreeViewController(); diff --git a/src/dao/choiceDao.ts b/src/dao/choiceDao.ts index ec3bba4..178f2ad 100644 --- a/src/dao/choiceDao.ts +++ b/src/dao/choiceDao.ts @@ -8,2088 +8,266 @@ */ class ChoiceDao { - - public getChoiceData() { - return this.choiceData; - } - - private choiceData = [ - { - "id": "shopee", - "name": "Shopee精选", - "questions": [ - 341, - 1000447, - 1000446, - 1000445, - 1000444, - 1000443, - 232, - 871, - 102, - 101, - 15, - 460, - 456, - 448, - 179, - 432, - 48, - 37, - 20, - 146 - ], - - }, - { - "id": "binary-search", - "name": "二分查找", - "questions": [ - 4, - 1550, - 540, - 1056, - 33, - 34, - 35, - 1059, - 1060, - 1083, - 2047, - 69, - 1605, - 74, - 1612, - 1102, - 1615, - 81, - 1621, - 1122, - 611, - 1645, - 1134, - 1646, - 1143, - 633, - 1149, - 644, - 1672, - 1675, - 1679, - 658, - 1684, - 153, - 154, - 668, - 1185, - 162, - 167, - 1192, - 1730, - 718, - 719, - 1232, - 209, - 1753, - 222, - 1249, - 1766, - 745, - 1771, - 1262, - 240, - 1290, - 270, - 786, - 275, - 788, - 278, - 792, - 794, - 1307, - 287, - 802, - 1831, - 1832, - 809, - 300, - 302, - 1326, - 1851, - 1352, - 853, - 350, - 1374, - 352, - 1886, - 1891, - 1384, - 363, - 367, - 882, - 374, - 378, - 894, - 1918, - 1408, - 1413, - 1929, - 907, - 912, - 1946, - 923, - 1957, - 1966, - 947, - 436, - 1463, - 441, - 1468, - 1984, - 1476, - 1486, - 2000, - 2006, - 2018, - 2027, - 2036, - 2045, - 1023 - ], - - }, - { - "id": "lcof", - "name": "剑指 Offer", - "questions": [ - 1000228, - 1000229, - 1000230, - 1000231, - 1000232, - 1000233, - 1000234, - 1000235, - 1000236, - 1000237, - 1000238, - 1000239, - 1000240, - 1000241, - 1000242, - 1000243, - 1000244, - 1000245, - 1000246, - 1000247, - 1000248, - 1000249, - 1000250, - 1000251, - 1000252, - 1000253, - 1000254, - 1000255, - 1000256, - 1000257, - 1000258, - 1000259, - 1000260, - 1000261, - 1000262, - 1000263, - 1000264, - 1000265, - 1000266, - 1000267, - 1000268, - 1000269, - 1000270, - 1000271, - 1000272, - 1000273, - 1000274, - 1000275, - 1000276, - 1000277, - 1000278, - 1000279, - 1000280, - 1000281, - 1000282, - 1000283, - 1000284, - 1000285, - 1000286, - 1000287, - 1000288, - 1000289, - 1000290, - 1000291, - 1000292, - 1000293, - 1000294, - 1000295, - 1000296, - 1000297, - 1000298, - 1000299, - 1000300, - 1000301, - 1000302, - 1000303, - 1000304, - 1000305, - 1000306, - 1000307, - 1000308, - 1000309, - 1000310, - 1000311, - 1000312, - 1000313, - 1000314, - 1000315, - 1000316, - 1000317, - 1000318, - 1000319, - 1000320, - 1000321, - 1000322, - 1000323, - 1000324, - 1000325, - 1000326, - 1000327, - 1000328, - 1000329, - 1000330, - 1000331, - 1000332, - 1000333, - 1000334, - 1000335, - 1000336, - 1000337, - 1000338, - 1000339, - 1000340, - 1000341, - 1000342, - 1000343, - 1000344, - 1000345, - 1000346, - 100273, - 100274, - 100275, - 100276, - 100277, - 100278, - 100279, - 100280, - 100281, - 100282, - 100283, - 100284, - 100285, - 100286, - 100287, - 100288, - 100289, - 100290, - 100291, - 100292, - 100293, - 100294, - 100295, - 100296, - 100297, - 100298, - 100299, - 100300, - 100301, - 100302, - 100303, - 100304, - 100305, - 100306, - 100307, - 100308, - 100309, - 100310, - 100311, - 100312, - 100313, - 100314, - 100315, - 100316, - 100317, - 100318, - 100319, - 100320, - 100321, - 100322, - 100323, - 100324, - 100325, - 100326, - 100327, - 100328, - 100329, - 100330, - 100331, - 100332, - 100333, - 100334, - 100335, - 100336, - 100337, - 100338, - 100339, - 100340, - 100341, - 100342, - 100343, - 100344, - 100345, - 100346, - 100347 - ], - - }, - { - "id": "e8X3pBZi", - "name": "剑指 Offer(专项突击版)", - "questions": [ - 1000228, - 1000229, - 1000230, - 1000231, - 1000232, - 1000233, - 1000234, - 1000235, - 1000236, - 1000237, - 1000238, - 1000239, - 1000240, - 1000241, - 1000242, - 1000243, - 1000244, - 1000245, - 1000246, - 1000247, - 1000248, - 1000249, - 1000250, - 1000251, - 1000252, - 1000253, - 1000254, - 1000255, - 1000256, - 1000257, - 1000258, - 1000259, - 1000260, - 1000261, - 1000262, - 1000263, - 1000264, - 1000265, - 1000266, - 1000267, - 1000268, - 1000269, - 1000270, - 1000271, - 1000272, - 1000273, - 1000274, - 1000275, - 1000276, - 1000277, - 1000278, - 1000279, - 1000280, - 1000281, - 1000282, - 1000283, - 1000284, - 1000285, - 1000286, - 1000287, - 1000288, - 1000289, - 1000290, - 1000291, - 1000292, - 1000293, - 1000294, - 1000295, - 1000296, - 1000297, - 1000298, - 1000299, - 1000300, - 1000301, - 1000302, - 1000303, - 1000304, - 1000305, - 1000306, - 1000307, - 1000308, - 1000309, - 1000310, - 1000311, - 1000312, - 1000313, - 1000314, - 1000315, - 1000316, - 1000317, - 1000318, - 1000319, - 1000320, - 1000321, - 1000322, - 1000323, - 1000324, - 1000325, - 1000326, - 1000327, - 1000328, - 1000329, - 1000330, - 1000331, - 1000332, - 1000333, - 1000334, - 1000335, - 1000336, - 1000337, - 1000338, - 1000339, - 1000340, - 1000341, - 1000342, - 1000343, - 1000344, - 1000345, - 1000346 - ], - - }, - { - "id": "xb9nqhhg", - "name": "剑指 Offer(第 2 版)", - "questions": [ - 100319, - 100328, - 100327, - 100326, - 100325, - 100324, - 100323, - 100322, - 100321, - 100320, - 100329, - 100318, - 100317, - 100316, - 100315, - 100314, - 100313, - 100312, - 100311, - 100338, - 100347, - 100346, - 100345, - 100344, - 100343, - 100342, - 100341, - 100340, - 100339, - 100310, - 100337, - 100336, - 100335, - 100334, - 100333, - 100332, - 100331, - 100330, - 100282, - 100291, - 100290, - 100289, - 100288, - 100287, - 100286, - 100285, - 100284, - 100283, - 100292, - 100281, - 100280, - 100279, - 100278, - 100277, - 100276, - 100275, - 100274, - 100301, - 100309, - 100308, - 100307, - 100306, - 100305, - 100304, - 100303, - 100302, - 100273, - 100300, - 100299, - 100298, - 100297, - 100296, - 100295, - 100294, - 100293 - ], - - }, - { - "id": "lccup", - "name": "力扣杯竞赛真题集", - "questions": [ - 1000134, - 1000222, - 1000362, - 1000367, - 1000368, - 1000369, - 1000370, - 1000371, - 1000373, - 1000374, - 1000375, - 1000130, - 1000131, - 1000132, - 1000133, - 100094, - 1000138, - 1000139, - 1000140, - 1000146, - 1000147, - 1000056, - 1000057, - 1000058, - 1000059, - 100092, - 100093, - 1000062, - 1000063, - 1000218, - 100107, - 1000085, - 1000086, - 1000087, - 1000088, - 1000089, - 1000090, - 1000091, - 1052, - 1053, - 1000093, - 1000215, - 1000216, - 100096, - 1058, - 1059, - 1060, - 1061, - 1000219, - 1000220, - 1000223, - 1000224, - 1000221, - 1000359, - 1000361, - 813, - 1069 - ], - - }, - { - "id": "dynamic-programming", - "name": "动态规划", - "questions": [ - 1025, - 514, - 516, - 5, - 518, - 10, - 526, - 1042, - 1559, - 1051, - 32, - 1057, - 546, - 1571, - 1060, - 549, - 39, - 40, - 1063, - 42, - 1067, - 1068, - 45, - 1583, - 562, - 53, - 55, - 568, - 62, - 63, - 64, - 576, - 70, - 72, - 1105, - 1617, - 600, - 91, - 96, - 1129, - 1130, - 1134, - 115, - 118, - 119, - 120, - 121, - 122, - 123, - 124, - 634, - 1669, - 646, - 647, - 650, - 139, - 140, - 651, - 1166, - 1680, - 1170, - 152, - 664, - 1178, - 1690, - 673, - 1196, - 174, - 688, - 1201, - 1202, - 691, - 698, - 188, - 1213, - 1220, - 198, - 712, - 714, - 1228, - 1744, - 1236, - 213, - 727, - 1240, - 1242, - 221, - 1758, - 1250, - 740, - 741, - 747, - 238, - 751, - 1263, - 1789, - 254, - 256, - 1286, - 264, - 265, - 1296, - 279, - 1822, - 1828, - 294, - 298, - 300, - 304, - 309, - 312, - 1851, - 322, - 1352, - 329, - 333, - 337, - 1361, - 343, - 351, - 867, - 1893, - 361, - 877, - 368, - 1906, - 1398, - 376, - 377, - 1402, - 1403, - 896, - 1924, - 392, - 911, - 923, - 413, - 1437, - 416, - 418, - 930, - 938, - 435, - 954, - 446, - 1471, - 1474, - 452, - 1989, - 967, - 1996, - 464, - 977, - 471, - 486, - 487, - 494, - 2031, - 1008, - 1522, - 1013, - 1017, - 1531, - 1022, - 1535 - ], - - }, - { - "id": "tusmiple", - "name": "图森未来", - "questions": [ - 718, - 127, - 1005, - 1000428, - 1000427, - 1000426, - 1000425, - 1000424, - 1000423, - 726, - 522, - 973, - 1217, - 193, - 1972, - 171, - 1957, - 36, - 27, - 1294 - ], - - }, - { - "id": "graph", - "name": "图论", - "questions": [ - 317, - 1912, - 1389, - 877, - 365, - 871, - 869, - 1380, - 352, - 863, - 323, - 895, - 310, - 820, - 305, - 1325, - 813, - 803, - 801, - 1309, - 1308, - 794, - 1986, - 505, - 2040, - 2038, - 2035, - 499, - 490, - 1492, - 1485, - 971, - 964, - 1815, - 960, - 949, - 433, - 1456, - 1447, - 1442, - 417, - 922, - 1428, - 1100, - 1191, - 1701, - 1696, - 1171, - 127, - 1661, - 1144, - 1117, - 1613, - 1101, - 1706, - 1085, - 1587, - 1073, - 1576, - 547, - 1058, - 542, - 1558, - 1039, - 721, - 1300, - 269, - 261, - 753, - 744, - 737, - 1757, - 733, - 1753, - 210, - 1032, - 207, - 1229, - 1738, - 200, - 1223, - 695, - 694, - 685, - 684 - ], - - }, - { - "id": "bytedancecampus", - "name": "字节校园", - "questions": [ - 69, - 88, - 215, - 206, - 76, - 200, - 72, - 199, - 198, - 92, - 322, - 64, - 56, - 54, - 53, - 948, - 46, - 300, - 94, - 102, - 103, - 232, - 105, - 236, - 239, - 1000185, - 1000182, - 1000183, - 1000184, - 121, - 1000186, - 1000187, - 124, - 135, - 146, - 143, - 142, - 15, - 14, - 141, - 394, - 1000188, - 20, - 7, - 129, - 5, - 4, - 3, - 2, - 1, - 128, - 21, - 22, - 23, - 151, - 25, - 152, - 792, - 923, - 31, - 160, - 33, - 415, - 41, - 42, - 43 - ], - - }, - { - "id": "ponyai", - "name": "小马智行 Pony.ai", - "questions": [ - 15, - 1000351, - 1000350, - 1000349, - 92, - 1000347, - 148, - 146, - 1105, - 1000352, - 909, - 173, - 1000348, - 105, - 39, - 1860, - 98, - 1441 - ], - - }, - { - "id": "cmbchina-cc", - "name": "招商银行信用卡", - "questions": [ - 33, - 124, - 103, - 88, - 199, - 198, - 322, - 64, - 53, - 41, - 1, - 415, - 923, - 22, - 21, - 20, - 15, - 7, - 5, - 3 - ], - }, - { - "id": "data-structures", - "name": "数据结构", - "questions": [ - 1, - 2, - 5, - 1032, - 15, - 1039, - 20, - 21, - 23, - 24, - 25, - 547, - 36, - 42, - 43, - 44, - 48, - 49, - 560, - 53, - 566, - 56, - 59, - 1085, - 73, - 1609, - 75, - 82, - 83, - 84, - 1107, - 88, - 94, - 98, - 101, - 102, - 103, - 104, - 105, - 108, - 112, - 113, - 118, - 119, - 121, - 124, - 1661, - 128, - 1665, - 642, - 136, - 138, - 141, - 142, - 143, - 144, - 145, - 653, - 148, - 155, - 1693, - 160, - 1701, - 169, - 173, - 1710, - 187, - 199, - 203, - 206, - 208, - 1745, - 211, - 212, - 214, - 215, - 217, - 218, - 729, - 226, - 739, - 230, - 232, - 235, - 236, - 238, - 1774, - 240, - 242, - 761, - 253, - 766, - 768, - 261, - 783, - 784, - 281, - 290, - 803, - 295, - 297, - 305, - 817, - 1345, - 323, - 325, - 838, - 334, - 336, - 337, - 347, - 1371, - 350, - 358, - 871, - 366, - 1903, - 369, - 378, - 892, - 383, - 387, - 394, - 402, - 409, - 922, - 415, - 1951, - 1442, - 1450, - 435, - 448, - 450, - 451, - 452, - 454, - 456, - 2009, - 1008, - 1014 - ], - - }, - { - "id": "xb9lfcwi", - "name": "程序员面试金典(第 6 版)", - "questions": [ - 100352, - 100353, - 100354, - 100355, - 100356, - 1000003, - 1000004, - 1000005, - 1000006, - 1000007, - 1000008, - 1000009, - 1000010, - 1000011, - 1000012, - 1000013, - 1000015, - 1000016, - 1000017, - 1000018, - 1000019, - 1000020, - 1000021, - 1000022, - 1000023, - 1000024, - 1000025, - 1000026, - 1000027, - 1000028, - 1000029, - 1000030, - 1000031, - 1000032, - 1000033, - 1000034, - 1000035, - 1000036, - 1000037, - 1000038, - 1000039, - 1000040, - 1000041, - 1000042, - 1000043, - 1000044, - 1000045, - 1000046, - 1000047, - 1000048, - 1000049, - 1000050, - 1000051, - 100158, - 100159, - 100160, - 100161, - 100162, - 100163, - 100164, - 100167, - 100168, - 100169, - 100170, - 100171, - 100172, - 100173, - 100174, - 100175, - 100176, - 100177, - 100178, - 100179, - 100180, - 100181, - 100182, - 100183, - 100184, - 100185, - 100186, - 100187, - 100188, - 100195, - 100196, - 100197, - 100198, - 100199, - 100200, - 100201, - 100202, - 100203, - 100228, - 100229, - 100230, - 100231, - 100232, - 100233, - 100240, - 100241, - 100242, - 100258, - 100259, - 100260, - 100261, - 100262, - 100348, - 100349, - 100350, - 100351 - ], - - }, - { - "id": "algorithms", - "name": "算法", - "questions": [ - 1025, - 3, - 4, - 5, - 1028, - 10, - 11, - 1036, - 1037, - 15, - 17, - 19, - 21, - 22, - 1046, - 542, - 33, - 34, - 35, - 547, - 37, - 1059, - 39, - 40, - 42, - 45, - 46, - 47, - 557, - 51, - 53, - 55, - 567, - 2047, - 572, - 62, - 70, - 582, - 72, - 583, - 74, - 1609, - 76, - 77, - 78, - 79, - 1101, - 82, - 85, - 90, - 91, - 617, - 1134, - 116, - 117, - 120, - 123, - 130, - 131, - 132, - 136, - 139, - 1165, - 146, - 1171, - 149, - 153, - 159, - 673, - 162, - 167, - 1192, - 174, - 695, - 189, - 190, - 191, - 198, - 200, - 201, - 202, - 713, - 714, - 715, - 206, - 207, - 209, - 210, - 213, - 221, - 733, - 1250, - 231, - 239, - 241, - 753, - 254, - 260, - 269, - 1300, - 278, - 792, - 283, - 286, - 287, - 800, - 300, - 301, - 813, - 309, - 310, - 315, - 322, - 329, - 337, - 340, - 343, - 344, - 865, - 874, - 893, - 895, - 384, - 394, - 908, - 410, - 413, - 416, - 417, - 1442, - 438, - 460, - 1485, - 2019, - 486, - 1512, - 1019, - 1023 - ], - - }, - { - "id": "programming-skills", - "name": "编程能力", - "questions": [ - 2, - 1031, - 8, - 525, - 23, - 535, - 28, - 43, - 556, - 48, - 49, - 1584, - 54, - 566, - 58, - 61, - 65, - 66, - 67, - 1626, - 1630, - 1125, - 104, - 110, - 631, - 635, - 642, - 138, - 1677, - 143, - 146, - 148, - 150, - 1176, - 155, - 1693, - 1708, - 173, - 1713, - 191, - 1728, - 1729, - 1736, - 713, - 202, - 715, - 208, - 209, - 211, - 214, - 1752, - 217, - 729, - 224, - 227, - 739, - 742, - 232, - 1768, - 1774, - 241, - 242, - 244, - 758, - 251, - 764, - 255, - 1791, - 771, - 1797, - 775, - 785, - 2322, - 281, - 282, - 283, - 295, - 297, - 303, - 304, - 307, - 325, - 838, - 1349, - 850, - 341, - 859, - 348, - 860, - 1888, - 353, - 1894, - 369, - 1905, - 885, - 890, - 1915, - 380, - 381, - 1406, - 1411, - 389, - 1930, - 908, - 404, - 1434, - 1949, - 1950, - 931, - 932, - 1955, - 937, - 946, - 1458, - 438, - 445, - 1982, - 449, - 1477, - 459, - 460, - 1484, - 1492, - 990, - 2015, - 1512, - 496, - 1014, - 503, - 1018 - ], - - }, - { - "id": "meituan", - "name": "美团真题", - "questions": [ - 1000192, - 1000193, - 1000194, - 1000195, - 1000196, - 1000197, - 1000198, - 1000199, - 1000200, - 1000201, - 1000202, - 1000203, - 1000189, - 1000190, - 1000191, - 257, - 100158, - 13, - 455, - 45, - 200, - 143, - 139, - 19, - 100344, - 162, - 177, - 75, - 1036, - 71, - 475, - 42, - 51, - 440, - 25 - ], - - }, - { - "id": "ke", - "name": "贝壳找房", - "questions": [ - 30, - 120, - 113, - 85, - 82, - 209, - 200, - 315, - 56, - 53, - 43, - 2, - 152, - 20, - 19, - 17, - 15, - 14, - 264, - 135, - 4 - ], - - }, - { - "id": "efficient-winning", - "name": "高效制胜", - "questions": [ - 230, - 329, - 79, - 720, - 218, - 1120, - 97, - 483, - 1508, - 456, - 112, - 496, - 1008, - 1013, - 119, - 121, - 122, - 416, - 3, - 11, - 524, - 15, - 18, - 20, - 279, - 28, - 1, - 803, - 167, - 42, - 53, - 825, - 322, - 70 - ], - - }, - { - "id": "2cktkvj", - "name": "LeetCode 热题 HOT 100", - "questions": [ - 160, - 236, - 234, - 739, - 226, - 221, - 215, - 208, - 207, - 206, - 200, - 198, - 169, - 238, - 155, - 152, - 148, - 146, - 142, - 141, - 139, - 136, - 647, - 128, - 124, - 322, - 494, - 461, - 448, - 438, - 437, - 416, - 406, - 399, - 394, - 347, - 338, - 337, - 121, - 312, - 309, - 301, - 300, - 297, - 287, - 283, - 279, - 253, - 240, - 239, - 22, - 49, - 48, - 46, - 42, - 39, - 543, - 34, - 33, - 32, - 31, - 538, - 23, - 560, - 21, - 20, - 19, - 17, - 15, - 11, - 10, - 5, - 4, - 3, - 2, - 79, - 114, - 621, - 617, - 105, - 104, - 102, - 101, - 98, - 96, - 94, - 85, - 84, - 1, - 78, - 76, - 75, - 72, - 70, - 581, - 64, - 62, - 56, - 55, - 53 - ], - - }, - { - "id": "7cyqwuv", - "name": "力扣杯 - 竞赛合集", - "questions": [ - 1000134, - 1000222, - 1000362, - 1000367, - 1000368, - 1000369, - 1000370, - 1000371, - 1000373, - 1000374, - 1000375, - 1000130, - 1000131, - 1000132, - 1000133, - 100094, - 1000138, - 1000139, - 1000140, - 1000146, - 1000147, - 1000056, - 1000057, - 1000058, - 1000059, - 100092, - 100093, - 1000062, - 1000063, - 1000216, - 100107, - 511, - 1000085, - 1000086, - 1000087, - 1000088, - 1000089, - 1000090, - 1000091, - 1052, - 1053, - 1000093, - 1000215, - 100096, - 1000218, - 1058, - 1059, - 1060, - 1061, - 1000219, - 1000220, - 1000223, - 1000224, - 1000221, - 1000359, - 1000361, - 1069 - ], - - }, - { - "id": "ex0k24j", - "name": "腾讯精选练习 50 题", - "questions": [ - 217, - 46, - 53, - 54, - 59, - 61, - 62, - 70, - 78, - 206, - 215, - 88, - 89, - 557, - 344, - 230, - 231, - 104, - 235, - 236, - 237, - 238, - 121, - 122, - 124, - 146, - 4, - 5, - 7, - 8, - 9, - 136, - 11, - 141, - 14, - 15, - 16, - 142, - 2, - 20, - 21, - 148, - 23, - 26, - 155, - 160, - 33, - 292, - 169, - 43 - ], - - }, - { - "id": "2ckc81c", - "name": "LeetCode 精选 TOP 面试题", - "questions": [ - 1, - 2, - 3, - 4, - 5, - 7, - 8, - 10, - 11, - 13, - 14, - 15, - 17, - 19, - 20, - 21, - 22, - 23, - 26, - 28, - 29, - 33, - 34, - 36, - 38, - 41, - 42, - 44, - 46, - 48, - 49, - 50, - 53, - 54, - 55, - 56, - 62, - 66, - 69, - 70, - 73, - 75, - 76, - 78, - 79, - 84, - 88, - 91, - 94, - 98, - 101, - 102, - 103, - 104, - 105, - 108, - 116, - 118, - 121, - 122, - 124, - 125, - 127, - 128, - 130, - 131, - 134, - 136, - 138, - 139, - 140, - 141, - 146, - 148, - 149, - 150, - 152, - 155, - 160, - 162, - 163, - 166, - 169, - 171, - 172, - 179, - 189, - 190, - 191, - 198, - 200, - 202, - 204, - 206, - 207, - 208, - 210, - 212, - 215, - 217, - 218, - 227, - 230, - 234, - 236, - 237, - 238, - 239, - 240, - 242, - 251, - 253, - 268, - 269, - 277, - 279, - 283, - 285, - 287, - 289, - 295, - 297, - 300, - 308, - 315, - 322, - 324, - 326, - 328, - 329, - 334, - 340, - 341, - 344, - 347, - 348, - 350, - 371, - 378, - 380, - 384, - 387, - 395, - 412, - 454 - ], - - } - ]; + public getChoiceData() { + return this.choiceData; + } + + private choiceData = [ + { + id: "shopee", + name: "Shopee精选", + questions: [ + 341, 1000447, 1000446, 1000445, 1000444, 1000443, 232, 871, 102, 101, 15, 460, 456, 448, 179, 432, 48, 37, 20, + 146, + ], + }, + { + id: "binary-search", + name: "二分查找", + questions: [ + 4, 1550, 540, 1056, 33, 34, 35, 1059, 1060, 1083, 2047, 69, 1605, 74, 1612, 1102, 1615, 81, 1621, 1122, 611, + 1645, 1134, 1646, 1143, 633, 1149, 644, 1672, 1675, 1679, 658, 1684, 153, 154, 668, 1185, 162, 167, 1192, 1730, + 718, 719, 1232, 209, 1753, 222, 1249, 1766, 745, 1771, 1262, 240, 1290, 270, 786, 275, 788, 278, 792, 794, 1307, + 287, 802, 1831, 1832, 809, 300, 302, 1326, 1851, 1352, 853, 350, 1374, 352, 1886, 1891, 1384, 363, 367, 882, + 374, 378, 894, 1918, 1408, 1413, 1929, 907, 912, 1946, 923, 1957, 1966, 947, 436, 1463, 441, 1468, 1984, 1476, + 1486, 2000, 2006, 2018, 2027, 2036, 2045, 1023, + ], + }, + { + id: "lcof", + name: "剑指 Offer", + questions: [ + 1000228, 1000229, 1000230, 1000231, 1000232, 1000233, 1000234, 1000235, 1000236, 1000237, 1000238, 1000239, + 1000240, 1000241, 1000242, 1000243, 1000244, 1000245, 1000246, 1000247, 1000248, 1000249, 1000250, 1000251, + 1000252, 1000253, 1000254, 1000255, 1000256, 1000257, 1000258, 1000259, 1000260, 1000261, 1000262, 1000263, + 1000264, 1000265, 1000266, 1000267, 1000268, 1000269, 1000270, 1000271, 1000272, 1000273, 1000274, 1000275, + 1000276, 1000277, 1000278, 1000279, 1000280, 1000281, 1000282, 1000283, 1000284, 1000285, 1000286, 1000287, + 1000288, 1000289, 1000290, 1000291, 1000292, 1000293, 1000294, 1000295, 1000296, 1000297, 1000298, 1000299, + 1000300, 1000301, 1000302, 1000303, 1000304, 1000305, 1000306, 1000307, 1000308, 1000309, 1000310, 1000311, + 1000312, 1000313, 1000314, 1000315, 1000316, 1000317, 1000318, 1000319, 1000320, 1000321, 1000322, 1000323, + 1000324, 1000325, 1000326, 1000327, 1000328, 1000329, 1000330, 1000331, 1000332, 1000333, 1000334, 1000335, + 1000336, 1000337, 1000338, 1000339, 1000340, 1000341, 1000342, 1000343, 1000344, 1000345, 1000346, 100273, + 100274, 100275, 100276, 100277, 100278, 100279, 100280, 100281, 100282, 100283, 100284, 100285, 100286, 100287, + 100288, 100289, 100290, 100291, 100292, 100293, 100294, 100295, 100296, 100297, 100298, 100299, 100300, 100301, + 100302, 100303, 100304, 100305, 100306, 100307, 100308, 100309, 100310, 100311, 100312, 100313, 100314, 100315, + 100316, 100317, 100318, 100319, 100320, 100321, 100322, 100323, 100324, 100325, 100326, 100327, 100328, 100329, + 100330, 100331, 100332, 100333, 100334, 100335, 100336, 100337, 100338, 100339, 100340, 100341, 100342, 100343, + 100344, 100345, 100346, 100347, + ], + }, + { + id: "e8X3pBZi", + name: "剑指 Offer(专项突击版)", + questions: [ + 1000228, 1000229, 1000230, 1000231, 1000232, 1000233, 1000234, 1000235, 1000236, 1000237, 1000238, 1000239, + 1000240, 1000241, 1000242, 1000243, 1000244, 1000245, 1000246, 1000247, 1000248, 1000249, 1000250, 1000251, + 1000252, 1000253, 1000254, 1000255, 1000256, 1000257, 1000258, 1000259, 1000260, 1000261, 1000262, 1000263, + 1000264, 1000265, 1000266, 1000267, 1000268, 1000269, 1000270, 1000271, 1000272, 1000273, 1000274, 1000275, + 1000276, 1000277, 1000278, 1000279, 1000280, 1000281, 1000282, 1000283, 1000284, 1000285, 1000286, 1000287, + 1000288, 1000289, 1000290, 1000291, 1000292, 1000293, 1000294, 1000295, 1000296, 1000297, 1000298, 1000299, + 1000300, 1000301, 1000302, 1000303, 1000304, 1000305, 1000306, 1000307, 1000308, 1000309, 1000310, 1000311, + 1000312, 1000313, 1000314, 1000315, 1000316, 1000317, 1000318, 1000319, 1000320, 1000321, 1000322, 1000323, + 1000324, 1000325, 1000326, 1000327, 1000328, 1000329, 1000330, 1000331, 1000332, 1000333, 1000334, 1000335, + 1000336, 1000337, 1000338, 1000339, 1000340, 1000341, 1000342, 1000343, 1000344, 1000345, 1000346, + ], + }, + { + id: "xb9nqhhg", + name: "剑指 Offer(第 2 版)", + questions: [ + 100319, 100328, 100327, 100326, 100325, 100324, 100323, 100322, 100321, 100320, 100329, 100318, 100317, 100316, + 100315, 100314, 100313, 100312, 100311, 100338, 100347, 100346, 100345, 100344, 100343, 100342, 100341, 100340, + 100339, 100310, 100337, 100336, 100335, 100334, 100333, 100332, 100331, 100330, 100282, 100291, 100290, 100289, + 100288, 100287, 100286, 100285, 100284, 100283, 100292, 100281, 100280, 100279, 100278, 100277, 100276, 100275, + 100274, 100301, 100309, 100308, 100307, 100306, 100305, 100304, 100303, 100302, 100273, 100300, 100299, 100298, + 100297, 100296, 100295, 100294, 100293, + ], + }, + { + id: "lccup", + name: "力扣杯竞赛真题集", + questions: [ + 1000134, 1000222, 1000362, 1000367, 1000368, 1000369, 1000370, 1000371, 1000373, 1000374, 1000375, 1000130, + 1000131, 1000132, 1000133, 100094, 1000138, 1000139, 1000140, 1000146, 1000147, 1000056, 1000057, 1000058, + 1000059, 100092, 100093, 1000062, 1000063, 1000218, 100107, 1000085, 1000086, 1000087, 1000088, 1000089, + 1000090, 1000091, 1052, 1053, 1000093, 1000215, 1000216, 100096, 1058, 1059, 1060, 1061, 1000219, 1000220, + 1000223, 1000224, 1000221, 1000359, 1000361, 813, 1069, + ], + }, + { + id: "dynamic-programming", + name: "动态规划", + questions: [ + 1025, 514, 516, 5, 518, 10, 526, 1042, 1559, 1051, 32, 1057, 546, 1571, 1060, 549, 39, 40, 1063, 42, 1067, 1068, + 45, 1583, 562, 53, 55, 568, 62, 63, 64, 576, 70, 72, 1105, 1617, 600, 91, 96, 1129, 1130, 1134, 115, 118, 119, + 120, 121, 122, 123, 124, 634, 1669, 646, 647, 650, 139, 140, 651, 1166, 1680, 1170, 152, 664, 1178, 1690, 673, + 1196, 174, 688, 1201, 1202, 691, 698, 188, 1213, 1220, 198, 712, 714, 1228, 1744, 1236, 213, 727, 1240, 1242, + 221, 1758, 1250, 740, 741, 747, 238, 751, 1263, 1789, 254, 256, 1286, 264, 265, 1296, 279, 1822, 1828, 294, 298, + 300, 304, 309, 312, 1851, 322, 1352, 329, 333, 337, 1361, 343, 351, 867, 1893, 361, 877, 368, 1906, 1398, 376, + 377, 1402, 1403, 896, 1924, 392, 911, 923, 413, 1437, 416, 418, 930, 938, 435, 954, 446, 1471, 1474, 452, 1989, + 967, 1996, 464, 977, 471, 486, 487, 494, 2031, 1008, 1522, 1013, 1017, 1531, 1022, 1535, + ], + }, + { + id: "tusmiple", + name: "图森未来", + questions: [ + 718, 127, 1005, 1000428, 1000427, 1000426, 1000425, 1000424, 1000423, 726, 522, 973, 1217, 193, 1972, 171, 1957, + 36, 27, 1294, + ], + }, + { + id: "graph", + name: "图论", + questions: [ + 317, 1912, 1389, 877, 365, 871, 869, 1380, 352, 863, 323, 895, 310, 820, 305, 1325, 813, 803, 801, 1309, 1308, + 794, 1986, 505, 2040, 2038, 2035, 499, 490, 1492, 1485, 971, 964, 1815, 960, 949, 433, 1456, 1447, 1442, 417, + 922, 1428, 1100, 1191, 1701, 1696, 1171, 127, 1661, 1144, 1117, 1613, 1101, 1706, 1085, 1587, 1073, 1576, 547, + 1058, 542, 1558, 1039, 721, 1300, 269, 261, 753, 744, 737, 1757, 733, 1753, 210, 1032, 207, 1229, 1738, 200, + 1223, 695, 694, 685, 684, + ], + }, + { + id: "bytedancecampus", + name: "字节校园", + questions: [ + 69, 88, 215, 206, 76, 200, 72, 199, 198, 92, 322, 64, 56, 54, 53, 948, 46, 300, 94, 102, 103, 232, 105, 236, + 239, 1000185, 1000182, 1000183, 1000184, 121, 1000186, 1000187, 124, 135, 146, 143, 142, 15, 14, 141, 394, + 1000188, 20, 7, 129, 5, 4, 3, 2, 1, 128, 21, 22, 23, 151, 25, 152, 792, 923, 31, 160, 33, 415, 41, 42, 43, + ], + }, + { + id: "ponyai", + name: "小马智行 Pony.ai", + questions: [ + 15, 1000351, 1000350, 1000349, 92, 1000347, 148, 146, 1105, 1000352, 909, 173, 1000348, 105, 39, 1860, 98, 1441, + ], + }, + { + id: "cmbchina-cc", + name: "招商银行信用卡", + questions: [33, 124, 103, 88, 199, 198, 322, 64, 53, 41, 1, 415, 923, 22, 21, 20, 15, 7, 5, 3], + }, + { + id: "data-structures", + name: "数据结构", + questions: [ + 1, 2, 5, 1032, 15, 1039, 20, 21, 23, 24, 25, 547, 36, 42, 43, 44, 48, 49, 560, 53, 566, 56, 59, 1085, 73, 1609, + 75, 82, 83, 84, 1107, 88, 94, 98, 101, 102, 103, 104, 105, 108, 112, 113, 118, 119, 121, 124, 1661, 128, 1665, + 642, 136, 138, 141, 142, 143, 144, 145, 653, 148, 155, 1693, 160, 1701, 169, 173, 1710, 187, 199, 203, 206, 208, + 1745, 211, 212, 214, 215, 217, 218, 729, 226, 739, 230, 232, 235, 236, 238, 1774, 240, 242, 761, 253, 766, 768, + 261, 783, 784, 281, 290, 803, 295, 297, 305, 817, 1345, 323, 325, 838, 334, 336, 337, 347, 1371, 350, 358, 871, + 366, 1903, 369, 378, 892, 383, 387, 394, 402, 409, 922, 415, 1951, 1442, 1450, 435, 448, 450, 451, 452, 454, + 456, 2009, 1008, 1014, + ], + }, + { + id: "xb9lfcwi", + name: "程序员面试金典(第 6 版)", + questions: [ + 100352, 100353, 100354, 100355, 100356, 1000003, 1000004, 1000005, 1000006, 1000007, 1000008, 1000009, 1000010, + 1000011, 1000012, 1000013, 1000015, 1000016, 1000017, 1000018, 1000019, 1000020, 1000021, 1000022, 1000023, + 1000024, 1000025, 1000026, 1000027, 1000028, 1000029, 1000030, 1000031, 1000032, 1000033, 1000034, 1000035, + 1000036, 1000037, 1000038, 1000039, 1000040, 1000041, 1000042, 1000043, 1000044, 1000045, 1000046, 1000047, + 1000048, 1000049, 1000050, 1000051, 100158, 100159, 100160, 100161, 100162, 100163, 100164, 100167, 100168, + 100169, 100170, 100171, 100172, 100173, 100174, 100175, 100176, 100177, 100178, 100179, 100180, 100181, 100182, + 100183, 100184, 100185, 100186, 100187, 100188, 100195, 100196, 100197, 100198, 100199, 100200, 100201, 100202, + 100203, 100228, 100229, 100230, 100231, 100232, 100233, 100240, 100241, 100242, 100258, 100259, 100260, 100261, + 100262, 100348, 100349, 100350, 100351, + ], + }, + { + id: "algorithms", + name: "算法", + questions: [ + 1025, 3, 4, 5, 1028, 10, 11, 1036, 1037, 15, 17, 19, 21, 22, 1046, 542, 33, 34, 35, 547, 37, 1059, 39, 40, 42, + 45, 46, 47, 557, 51, 53, 55, 567, 2047, 572, 62, 70, 582, 72, 583, 74, 1609, 76, 77, 78, 79, 1101, 82, 85, 90, + 91, 617, 1134, 116, 117, 120, 123, 130, 131, 132, 136, 139, 1165, 146, 1171, 149, 153, 159, 673, 162, 167, 1192, + 174, 695, 189, 190, 191, 198, 200, 201, 202, 713, 714, 715, 206, 207, 209, 210, 213, 221, 733, 1250, 231, 239, + 241, 753, 254, 260, 269, 1300, 278, 792, 283, 286, 287, 800, 300, 301, 813, 309, 310, 315, 322, 329, 337, 340, + 343, 344, 865, 874, 893, 895, 384, 394, 908, 410, 413, 416, 417, 1442, 438, 460, 1485, 2019, 486, 1512, 1019, + 1023, + ], + }, + { + id: "programming-skills", + name: "编程能力", + questions: [ + 2, 1031, 8, 525, 23, 535, 28, 43, 556, 48, 49, 1584, 54, 566, 58, 61, 65, 66, 67, 1626, 1630, 1125, 104, 110, + 631, 635, 642, 138, 1677, 143, 146, 148, 150, 1176, 155, 1693, 1708, 173, 1713, 191, 1728, 1729, 1736, 713, 202, + 715, 208, 209, 211, 214, 1752, 217, 729, 224, 227, 739, 742, 232, 1768, 1774, 241, 242, 244, 758, 251, 764, 255, + 1791, 771, 1797, 775, 785, 2322, 281, 282, 283, 295, 297, 303, 304, 307, 325, 838, 1349, 850, 341, 859, 348, + 860, 1888, 353, 1894, 369, 1905, 885, 890, 1915, 380, 381, 1406, 1411, 389, 1930, 908, 404, 1434, 1949, 1950, + 931, 932, 1955, 937, 946, 1458, 438, 445, 1982, 449, 1477, 459, 460, 1484, 1492, 990, 2015, 1512, 496, 1014, + 503, 1018, + ], + }, + { + id: "meituan", + name: "美团真题", + questions: [ + 1000192, 1000193, 1000194, 1000195, 1000196, 1000197, 1000198, 1000199, 1000200, 1000201, 1000202, 1000203, + 1000189, 1000190, 1000191, 257, 100158, 13, 455, 45, 200, 143, 139, 19, 100344, 162, 177, 75, 1036, 71, 475, 42, + 51, 440, 25, + ], + }, + { + id: "ke", + name: "贝壳找房", + questions: [30, 120, 113, 85, 82, 209, 200, 315, 56, 53, 43, 2, 152, 20, 19, 17, 15, 14, 264, 135, 4], + }, + { + id: "efficient-winning", + name: "高效制胜", + questions: [ + 230, 329, 79, 720, 218, 1120, 97, 483, 1508, 456, 112, 496, 1008, 1013, 119, 121, 122, 416, 3, 11, 524, 15, 18, + 20, 279, 28, 1, 803, 167, 42, 53, 825, 322, 70, + ], + }, + { + id: "2cktkvj", + name: "LeetCode 热题 HOT 100", + questions: [ + 160, 236, 234, 739, 226, 221, 215, 208, 207, 206, 200, 198, 169, 238, 155, 152, 148, 146, 142, 141, 139, 136, + 647, 128, 124, 322, 494, 461, 448, 438, 437, 416, 406, 399, 394, 347, 338, 337, 121, 312, 309, 301, 300, 297, + 287, 283, 279, 253, 240, 239, 22, 49, 48, 46, 42, 39, 543, 34, 33, 32, 31, 538, 23, 560, 21, 20, 19, 17, 15, 11, + 10, 5, 4, 3, 2, 79, 114, 621, 617, 105, 104, 102, 101, 98, 96, 94, 85, 84, 1, 78, 76, 75, 72, 70, 581, 64, 62, + 56, 55, 53, + ], + }, + { + id: "7cyqwuv", + name: "力扣杯 - 竞赛合集", + questions: [ + 1000134, 1000222, 1000362, 1000367, 1000368, 1000369, 1000370, 1000371, 1000373, 1000374, 1000375, 1000130, + 1000131, 1000132, 1000133, 100094, 1000138, 1000139, 1000140, 1000146, 1000147, 1000056, 1000057, 1000058, + 1000059, 100092, 100093, 1000062, 1000063, 1000216, 100107, 511, 1000085, 1000086, 1000087, 1000088, 1000089, + 1000090, 1000091, 1052, 1053, 1000093, 1000215, 100096, 1000218, 1058, 1059, 1060, 1061, 1000219, 1000220, + 1000223, 1000224, 1000221, 1000359, 1000361, 1069, + ], + }, + { + id: "ex0k24j", + name: "腾讯精选练习 50 题", + questions: [ + 217, 46, 53, 54, 59, 61, 62, 70, 78, 206, 215, 88, 89, 557, 344, 230, 231, 104, 235, 236, 237, 238, 121, 122, + 124, 146, 4, 5, 7, 8, 9, 136, 11, 141, 14, 15, 16, 142, 2, 20, 21, 148, 23, 26, 155, 160, 33, 292, 169, 43, + ], + }, + { + id: "2ckc81c", + name: "LeetCode 精选 TOP 面试题", + questions: [ + 1, 2, 3, 4, 5, 7, 8, 10, 11, 13, 14, 15, 17, 19, 20, 21, 22, 23, 26, 28, 29, 33, 34, 36, 38, 41, 42, 44, 46, 48, + 49, 50, 53, 54, 55, 56, 62, 66, 69, 70, 73, 75, 76, 78, 79, 84, 88, 91, 94, 98, 101, 102, 103, 104, 105, 108, + 116, 118, 121, 122, 124, 125, 127, 128, 130, 131, 134, 136, 138, 139, 140, 141, 146, 148, 149, 150, 152, 155, + 160, 162, 163, 166, 169, 171, 172, 179, 189, 190, 191, 198, 200, 202, 204, 206, 207, 208, 210, 212, 215, 217, + 218, 227, 230, 234, 236, 237, 238, 239, 240, 242, 251, 253, 268, 269, 277, 279, 283, 285, 287, 289, 295, 297, + 300, 308, 315, 322, 324, 326, 328, 329, 334, 340, 341, 344, 347, 348, 350, 371, 378, 380, 384, 387, 395, 412, + 454, + ], + }, + ]; } - export const choiceDao: ChoiceDao = new ChoiceDao(); - - - - - - diff --git a/src/dao/scoreDao.ts b/src/dao/scoreDao.ts index 211ac43..e737d86 100644 --- a/src/dao/scoreDao.ts +++ b/src/dao/scoreDao.ts @@ -9,35 +9,24 @@ import { IScoreData } from "../model/Model"; - - - class ScoreDao { - private scoreBase = require("../../../resources/data.json"); + private scoreBase = require("../../../resources/data.json"); - public getScoreData(onlineData?): Map { - - let nameSiteMapping = new Map (); - let temp = this.scoreBase as IScoreData[]; - if (onlineData) { - temp = onlineData; - } - temp.forEach(element => { - // Rating - // ID - // ContestSlug - element.score = "" + Math.floor(element.Rating || 0); - nameSiteMapping.set("" + element.ID, element); - }); - return nameSiteMapping; + public getScoreData(onlineData?): Map { + let nameSiteMapping = new Map (); + let temp = this.scoreBase as IScoreData[]; + if (onlineData) { + temp = onlineData; } + temp.forEach((element) => { + // Rating + // ID + // ContestSlug + element.score = "" + Math.floor(element.Rating || 0); + nameSiteMapping.set("" + element.ID, element); + }); + return nameSiteMapping; + } } - export const scoreDao: ScoreDao = new ScoreDao(); - - - - - - diff --git a/src/dao/tagsDao.ts b/src/dao/tagsDao.ts index 42ee915..eeca573 100644 --- a/src/dao/tagsDao.ts +++ b/src/dao/tagsDao.ts @@ -7,2892 +7,4676 @@ * Copyright (c) 2022 ccagml . All rights reserved. */ - - class TagsDao { + private tagsData = { + "1": { topicTags: ["array", "hash-table"] }, + "2": { topicTags: ["recursion", "linked-list", "math"] }, + "3": { topicTags: ["hash-table", "string", "sliding-window"] }, + "4": { topicTags: ["array", "binary-search", "divide-and-conquer"] }, + "5": { topicTags: ["string", "dynamic-programming"] }, + "6": { topicTags: ["string"] }, + "7": { topicTags: ["math"] }, + "8": { topicTags: ["string"] }, + "9": { topicTags: ["math"] }, + "10": { topicTags: ["recursion", "string", "dynamic-programming"] }, + "11": { topicTags: ["greedy", "array", "two-pointers"] }, + "12": { topicTags: ["hash-table", "math", "string"] }, + "13": { topicTags: ["hash-table", "math", "string"] }, + "14": { topicTags: ["string"] }, + "15": { topicTags: ["array", "two-pointers", "sorting"] }, + "16": { topicTags: ["array", "two-pointers", "sorting"] }, + "17": { topicTags: ["hash-table", "string", "backtracking"] }, + "18": { topicTags: ["array", "two-pointers", "sorting"] }, + "19": { topicTags: ["linked-list", "two-pointers"] }, + "20": { topicTags: ["stack", "string"] }, + "21": { topicTags: ["recursion", "linked-list"] }, + "22": { topicTags: ["string", "dynamic-programming", "backtracking"] }, + "23": { + topicTags: ["linked-list", "divide-and-conquer", "heap-priority-queue", "merge-sort"], + }, + "24": { topicTags: ["recursion", "linked-list"] }, + "25": { topicTags: ["recursion", "linked-list"] }, + "26": { topicTags: ["array", "two-pointers"] }, + "27": { topicTags: ["array", "two-pointers"] }, + "28": { topicTags: ["two-pointers", "string", "string-matching"] }, + "29": { topicTags: ["bit-manipulation", "math"] }, + "30": { topicTags: ["hash-table", "string", "sliding-window"] }, + "31": { topicTags: ["array", "two-pointers"] }, + "32": { topicTags: ["stack", "string", "dynamic-programming"] }, + "33": { topicTags: ["array", "binary-search"] }, + "34": { topicTags: ["array", "binary-search"] }, + "35": { topicTags: ["array", "binary-search"] }, + "36": { topicTags: ["array", "hash-table", "matrix"] }, + "37": { topicTags: ["array", "backtracking", "matrix"] }, + "38": { topicTags: ["string"] }, + "39": { topicTags: ["array", "backtracking"] }, + "40": { topicTags: ["array", "backtracking"] }, + "41": { topicTags: ["array", "hash-table"] }, + "42": { + topicTags: ["stack", "array", "two-pointers", "dynamic-programming", "monotonic-stack"], + }, + "43": { topicTags: ["math", "string", "simulation"] }, + "44": { + topicTags: ["greedy", "recursion", "string", "dynamic-programming"], + }, + "45": { topicTags: ["greedy", "array", "dynamic-programming"] }, + "46": { topicTags: ["array", "backtracking"] }, + "47": { topicTags: ["array", "backtracking"] }, + "48": { topicTags: ["array", "math", "matrix"] }, + "49": { topicTags: ["array", "hash-table", "string", "sorting"] }, + "50": { topicTags: ["recursion", "math"] }, + "51": { topicTags: ["array", "backtracking"] }, + "52": { topicTags: ["backtracking"] }, + "53": { topicTags: ["array", "divide-and-conquer", "dynamic-programming"] }, + "54": { topicTags: ["array", "matrix", "simulation"] }, + "55": { topicTags: ["greedy", "array", "dynamic-programming"] }, + "56": { topicTags: ["array", "sorting"] }, + "57": { topicTags: ["array"] }, + "58": { topicTags: ["string"] }, + "59": { topicTags: ["array", "matrix", "simulation"] }, + "60": { topicTags: ["recursion", "math"] }, + "61": { topicTags: ["linked-list", "two-pointers"] }, + "62": { topicTags: ["math", "dynamic-programming", "combinatorics"] }, + "63": { topicTags: ["array", "dynamic-programming", "matrix"] }, + "64": { topicTags: ["array", "dynamic-programming", "matrix"] }, + "65": { topicTags: ["string"] }, + "66": { topicTags: ["array", "math"] }, + "67": { topicTags: ["bit-manipulation", "math", "string", "simulation"] }, + "68": { topicTags: ["array", "string", "simulation"] }, + "69": { topicTags: ["math", "binary-search"] }, + "70": { topicTags: ["memoization", "math", "dynamic-programming"] }, + "71": { topicTags: ["stack", "string"] }, + "72": { topicTags: ["string", "dynamic-programming"] }, + "73": { topicTags: ["array", "hash-table", "matrix"] }, + "74": { topicTags: ["array", "binary-search", "matrix"] }, + "75": { topicTags: ["array", "two-pointers", "sorting"] }, + "76": { topicTags: ["hash-table", "string", "sliding-window"] }, + "77": { topicTags: ["backtracking"] }, + "78": { topicTags: ["bit-manipulation", "array", "backtracking"] }, + "79": { topicTags: ["array", "backtracking", "matrix"] }, + "80": { topicTags: ["array", "two-pointers"] }, + "81": { topicTags: ["array", "binary-search"] }, + "82": { topicTags: ["linked-list", "two-pointers"] }, + "83": { topicTags: ["linked-list"] }, + "84": { topicTags: ["stack", "array", "monotonic-stack"] }, + "85": { + topicTags: ["stack", "array", "dynamic-programming", "matrix", "monotonic-stack"], + }, + "86": { topicTags: ["linked-list", "two-pointers"] }, + "87": { topicTags: ["string", "dynamic-programming"] }, + "88": { topicTags: ["array", "two-pointers", "sorting"] }, + "89": { topicTags: ["bit-manipulation", "math", "backtracking"] }, + "90": { topicTags: ["bit-manipulation", "array", "backtracking"] }, + "91": { topicTags: ["string", "dynamic-programming"] }, + "92": { topicTags: ["linked-list"] }, + "93": { topicTags: ["string", "backtracking"] }, + "94": { topicTags: ["stack", "tree", "depth-first-search", "binary-tree"] }, + "95": { + topicTags: ["tree", "binary-search-tree", "dynamic-programming", "backtracking", "binary-tree"], + }, + "96": { + topicTags: ["tree", "binary-search-tree", "math", "dynamic-programming", "binary-tree"], + }, + "97": { topicTags: ["string", "dynamic-programming"] }, + "98": { + topicTags: ["tree", "depth-first-search", "binary-search-tree", "binary-tree"], + }, + "99": { + topicTags: ["tree", "depth-first-search", "binary-search-tree", "binary-tree"], + }, + "100": { + topicTags: ["tree", "depth-first-search", "breadth-first-search", "binary-tree"], + }, + "101": { + topicTags: ["tree", "depth-first-search", "breadth-first-search", "binary-tree"], + }, + "102": { topicTags: ["tree", "breadth-first-search", "binary-tree"] }, + "103": { topicTags: ["tree", "breadth-first-search", "binary-tree"] }, + "104": { + topicTags: ["tree", "depth-first-search", "breadth-first-search", "binary-tree"], + }, + "105": { + topicTags: ["tree", "array", "hash-table", "divide-and-conquer", "binary-tree"], + }, + "106": { + topicTags: ["tree", "array", "hash-table", "divide-and-conquer", "binary-tree"], + }, + "107": { topicTags: ["tree", "breadth-first-search", "binary-tree"] }, + "108": { + topicTags: ["tree", "binary-search-tree", "array", "divide-and-conquer", "binary-tree"], + }, + "109": { + topicTags: ["tree", "binary-search-tree", "linked-list", "divide-and-conquer", "binary-tree"], + }, + "110": { topicTags: ["tree", "depth-first-search", "binary-tree"] }, + "111": { + topicTags: ["tree", "depth-first-search", "breadth-first-search", "binary-tree"], + }, + "112": { + topicTags: ["tree", "depth-first-search", "breadth-first-search", "binary-tree"], + }, + "113": { + topicTags: ["tree", "depth-first-search", "backtracking", "binary-tree"], + }, + "114": { + topicTags: ["stack", "tree", "depth-first-search", "linked-list", "binary-tree"], + }, + "115": { topicTags: ["string", "dynamic-programming"] }, + "116": { + topicTags: ["tree", "depth-first-search", "breadth-first-search", "linked-list", "binary-tree"], + }, + "117": { + topicTags: ["tree", "depth-first-search", "breadth-first-search", "linked-list", "binary-tree"], + }, + "118": { topicTags: ["array", "dynamic-programming"] }, + "119": { topicTags: ["array", "dynamic-programming"] }, + "120": { topicTags: ["array", "dynamic-programming"] }, + "121": { topicTags: ["array", "dynamic-programming"] }, + "122": { topicTags: ["greedy", "array", "dynamic-programming"] }, + "123": { topicTags: ["array", "dynamic-programming"] }, + "124": { + topicTags: ["tree", "depth-first-search", "dynamic-programming", "binary-tree"], + }, + "125": { topicTags: ["two-pointers", "string"] }, + "126": { + topicTags: ["breadth-first-search", "hash-table", "string", "backtracking"], + }, + "127": { topicTags: ["breadth-first-search", "hash-table", "string"] }, + "128": { topicTags: ["union-find", "array", "hash-table"] }, + "129": { topicTags: ["tree", "depth-first-search", "binary-tree"] }, + "130": { + topicTags: ["depth-first-search", "breadth-first-search", "union-find", "array", "matrix"], + }, + "131": { topicTags: ["string", "dynamic-programming", "backtracking"] }, + "132": { topicTags: ["string", "dynamic-programming"] }, + "133": { + topicTags: ["depth-first-search", "breadth-first-search", "graph", "hash-table"], + }, + "134": { topicTags: ["greedy", "array"] }, + "135": { topicTags: ["greedy", "array"] }, + "136": { topicTags: ["bit-manipulation", "array"] }, + "137": { topicTags: ["bit-manipulation", "array"] }, + "138": { topicTags: ["hash-table", "linked-list"] }, + "139": { + topicTags: ["trie", "memoization", "hash-table", "string", "dynamic-programming"], + }, + "140": { + topicTags: ["trie", "memoization", "hash-table", "string", "dynamic-programming", "backtracking"], + }, + "141": { topicTags: ["hash-table", "linked-list", "two-pointers"] }, + "142": { topicTags: ["hash-table", "linked-list", "two-pointers"] }, + "143": { topicTags: ["stack", "recursion", "linked-list", "two-pointers"] }, + "144": { + topicTags: ["stack", "tree", "depth-first-search", "binary-tree"], + }, + "145": { + topicTags: ["stack", "tree", "depth-first-search", "binary-tree"], + }, + "146": { + topicTags: ["design", "hash-table", "linked-list", "doubly-linked-list"], + }, + "147": { topicTags: ["linked-list", "sorting"] }, + "148": { + topicTags: ["linked-list", "two-pointers", "divide-and-conquer", "sorting", "merge-sort"], + }, + "149": { topicTags: ["geometry", "array", "hash-table", "math"] }, + "150": { topicTags: ["stack", "array", "math"] }, + "151": { topicTags: ["two-pointers", "string"] }, + "152": { topicTags: ["array", "dynamic-programming"] }, + "153": { topicTags: ["array", "binary-search"] }, + "154": { topicTags: ["array", "binary-search"] }, + "155": { topicTags: ["stack", "design"] }, + "156": { topicTags: ["tree", "depth-first-search", "binary-tree"] }, + "157": { topicTags: ["string", "interactive", "simulation"] }, + "158": { topicTags: ["string", "interactive", "simulation"] }, + "159": { topicTags: ["hash-table", "string", "sliding-window"] }, + "160": { topicTags: ["hash-table", "linked-list", "two-pointers"] }, + "161": { topicTags: ["two-pointers", "string"] }, + "162": { topicTags: ["array", "binary-search"] }, + "163": { topicTags: ["array"] }, + "164": { topicTags: ["array", "bucket-sort", "radix-sort", "sorting"] }, + "165": { topicTags: ["two-pointers", "string"] }, + "166": { topicTags: ["hash-table", "math", "string"] }, + "167": { topicTags: ["array", "two-pointers", "binary-search"] }, + "168": { topicTags: ["math", "string"] }, + "169": { + topicTags: ["array", "hash-table", "divide-and-conquer", "counting", "sorting"], + }, + "170": { + topicTags: ["design", "array", "hash-table", "two-pointers", "data-stream"], + }, + "171": { topicTags: ["math", "string"] }, + "172": { topicTags: ["math"] }, + "173": { + topicTags: ["stack", "tree", "design", "binary-search-tree", "binary-tree", "iterator"], + }, + "174": { topicTags: ["array", "dynamic-programming", "matrix"] }, + "175": { topicTags: ["database"] }, + "176": { topicTags: ["database"] }, + "177": { topicTags: ["database"] }, + "178": { topicTags: ["database"] }, + "179": { topicTags: ["greedy", "string", "sorting"] }, + "180": { topicTags: ["database"] }, + "181": { topicTags: ["database"] }, + "182": { topicTags: ["database"] }, + "183": { topicTags: ["database"] }, + "184": { topicTags: ["database"] }, + "185": { topicTags: ["database"] }, + "186": { topicTags: ["two-pointers", "string"] }, + "187": { + topicTags: ["bit-manipulation", "hash-table", "string", "sliding-window", "hash-function", "rolling-hash"], + }, + "188": { topicTags: ["array", "dynamic-programming"] }, + "189": { topicTags: ["array", "math", "two-pointers"] }, + "190": { topicTags: ["bit-manipulation", "divide-and-conquer"] }, + "191": { topicTags: ["bit-manipulation", "divide-and-conquer"] }, + "192": { topicTags: ["shell"] }, + "193": { topicTags: ["shell"] }, + "194": { topicTags: ["shell"] }, + "195": { topicTags: ["shell"] }, + "196": { topicTags: ["database"] }, + "197": { topicTags: ["database"] }, + "198": { topicTags: ["array", "dynamic-programming"] }, + "199": { + topicTags: ["tree", "depth-first-search", "breadth-first-search", "binary-tree"], + }, + "200": { + topicTags: ["depth-first-search", "breadth-first-search", "union-find", "array", "matrix"], + }, + "201": { topicTags: ["bit-manipulation"] }, + "202": { topicTags: ["hash-table", "math", "two-pointers"] }, + "203": { topicTags: ["recursion", "linked-list"] }, + "204": { topicTags: ["array", "math", "enumeration", "number-theory"] }, + "205": { topicTags: ["hash-table", "string"] }, + "206": { topicTags: ["recursion", "linked-list"] }, + "207": { + topicTags: ["depth-first-search", "breadth-first-search", "graph", "topological-sort"], + }, + "208": { topicTags: ["design", "trie", "hash-table", "string"] }, + "209": { + topicTags: ["array", "binary-search", "prefix-sum", "sliding-window"], + }, + "210": { + topicTags: ["depth-first-search", "breadth-first-search", "graph", "topological-sort"], + }, + "211": { topicTags: ["depth-first-search", "design", "trie", "string"] }, + "212": { topicTags: ["trie", "array", "string", "backtracking", "matrix"] }, + "213": { topicTags: ["array", "dynamic-programming"] }, + "214": { + topicTags: ["string", "string-matching", "hash-function", "rolling-hash"], + }, + "215": { + topicTags: ["array", "divide-and-conquer", "quickselect", "sorting", "heap-priority-queue"], + }, + "216": { topicTags: ["array", "backtracking"] }, + "217": { topicTags: ["array", "hash-table", "sorting"] }, + "218": { + topicTags: [ + "binary-indexed-tree", + "segment-tree", + "array", + "divide-and-conquer", + "ordered-set", + "line-sweep", + "heap-priority-queue", + ], + }, + "219": { topicTags: ["array", "hash-table", "sliding-window"] }, + "220": { + topicTags: ["array", "bucket-sort", "ordered-set", "sorting", "sliding-window"], + }, + "221": { topicTags: ["array", "dynamic-programming", "matrix"] }, + "222": { + topicTags: ["tree", "depth-first-search", "binary-search", "binary-tree"], + }, + "223": { topicTags: ["geometry", "math"] }, + "224": { topicTags: ["stack", "recursion", "math", "string"] }, + "225": { topicTags: ["stack", "design", "queue"] }, + "226": { + topicTags: ["tree", "depth-first-search", "breadth-first-search", "binary-tree"], + }, + "227": { topicTags: ["stack", "math", "string"] }, + "228": { topicTags: ["array"] }, + "229": { topicTags: ["array", "hash-table", "counting", "sorting"] }, + "230": { + topicTags: ["tree", "depth-first-search", "binary-search-tree", "binary-tree"], + }, + "231": { topicTags: ["bit-manipulation", "recursion", "math"] }, + "232": { topicTags: ["stack", "design", "queue"] }, + "233": { topicTags: ["recursion", "math", "dynamic-programming"] }, + "234": { topicTags: ["stack", "recursion", "linked-list", "two-pointers"] }, + "235": { + topicTags: ["tree", "depth-first-search", "binary-search-tree", "binary-tree"], + }, + "236": { topicTags: ["tree", "depth-first-search", "binary-tree"] }, + "237": { topicTags: ["linked-list"] }, + "238": { topicTags: ["array", "prefix-sum"] }, + "239": { + topicTags: ["queue", "array", "sliding-window", "monotonic-queue", "heap-priority-queue"], + }, + "240": { + topicTags: ["array", "binary-search", "divide-and-conquer", "matrix"], + }, + "241": { + topicTags: ["recursion", "memoization", "math", "string", "dynamic-programming"], + }, + "242": { topicTags: ["hash-table", "string", "sorting"] }, + "243": { topicTags: ["array", "string"] }, + "244": { + topicTags: ["design", "array", "hash-table", "two-pointers", "string"], + }, + "245": { topicTags: ["array", "string"] }, + "246": { topicTags: ["hash-table", "two-pointers", "string"] }, + "247": { topicTags: ["recursion", "array", "string"] }, + "248": { topicTags: ["recursion", "array", "string"] }, + "249": { topicTags: ["array", "hash-table", "string"] }, + "250": { topicTags: ["tree", "depth-first-search", "binary-tree"] }, + "251": { topicTags: ["design", "array", "two-pointers", "iterator"] }, + "252": { topicTags: ["array", "sorting"] }, + "253": { + topicTags: ["greedy", "array", "two-pointers", "prefix-sum", "sorting", "heap-priority-queue"], + }, + "254": { topicTags: ["array", "backtracking"] }, + "255": { + topicTags: ["stack", "tree", "binary-search-tree", "recursion", "binary-tree", "monotonic-stack"], + }, + "256": { topicTags: ["array", "dynamic-programming"] }, + "257": { + topicTags: ["tree", "depth-first-search", "string", "backtracking", "binary-tree"], + }, + "258": { topicTags: ["math", "number-theory", "simulation"] }, + "259": { topicTags: ["array", "two-pointers", "binary-search", "sorting"] }, + "260": { topicTags: ["bit-manipulation", "array"] }, + "261": { + topicTags: ["depth-first-search", "breadth-first-search", "union-find", "graph"], + }, + "262": { topicTags: ["database"] }, + "263": { topicTags: ["math"] }, + "264": { + topicTags: ["hash-table", "math", "dynamic-programming", "heap-priority-queue"], + }, + "265": { topicTags: ["array", "dynamic-programming"] }, + "266": { topicTags: ["bit-manipulation", "hash-table", "string"] }, + "267": { topicTags: ["hash-table", "string", "backtracking"] }, + "268": { + topicTags: ["bit-manipulation", "array", "hash-table", "math", "binary-search", "sorting"], + }, + "269": { + topicTags: ["depth-first-search", "breadth-first-search", "graph", "topological-sort", "array", "string"], + }, + "270": { + topicTags: ["tree", "depth-first-search", "binary-search-tree", "binary-search", "binary-tree"], + }, + "271": { topicTags: ["design", "array", "string"] }, + "272": { + topicTags: [ + "stack", + "tree", + "depth-first-search", + "binary-search-tree", + "two-pointers", + "binary-tree", + "heap-priority-queue", + ], + }, + "273": { topicTags: ["recursion", "math", "string"] }, + "274": { topicTags: ["array", "counting-sort", "sorting"] }, + "275": { topicTags: ["array", "binary-search"] }, + "276": { topicTags: ["dynamic-programming"] }, + "277": { topicTags: ["greedy", "graph", "two-pointers", "interactive"] }, + "278": { topicTags: ["binary-search", "interactive"] }, + "279": { + topicTags: ["breadth-first-search", "math", "dynamic-programming"], + }, + "280": { topicTags: ["greedy", "array", "sorting"] }, + "281": { topicTags: ["design", "queue", "array", "iterator"] }, + "282": { topicTags: ["math", "string", "backtracking"] }, + "283": { topicTags: ["array", "two-pointers"] }, + "284": { topicTags: ["design", "array", "iterator"] }, + "285": { + topicTags: ["tree", "depth-first-search", "binary-search-tree", "binary-tree"], + }, + "286": { topicTags: ["breadth-first-search", "array", "matrix"] }, + "287": { + topicTags: ["bit-manipulation", "array", "two-pointers", "binary-search"], + }, + "288": { topicTags: ["design", "array", "hash-table", "string"] }, + "289": { topicTags: ["array", "matrix", "simulation"] }, + "290": { topicTags: ["hash-table", "string"] }, + "291": { topicTags: ["hash-table", "string", "backtracking"] }, + "292": { topicTags: ["brainteaser", "math", "game-theory"] }, + "293": { topicTags: ["string"] }, + "294": { + topicTags: ["memoization", "math", "dynamic-programming", "backtracking", "game-theory"], + }, + "295": { + topicTags: ["design", "two-pointers", "data-stream", "sorting", "heap-priority-queue"], + }, + "296": { topicTags: ["array", "math", "matrix", "sorting"] }, + "297": { + topicTags: ["tree", "depth-first-search", "breadth-first-search", "design", "string", "binary-tree"], + }, + "298": { topicTags: ["tree", "depth-first-search", "binary-tree"] }, + "299": { topicTags: ["hash-table", "string", "counting"] }, + "300": { topicTags: ["array", "binary-search", "dynamic-programming"] }, + "301": { topicTags: ["breadth-first-search", "string", "backtracking"] }, + "302": { + topicTags: ["depth-first-search", "breadth-first-search", "array", "binary-search", "matrix"], + }, + "303": { topicTags: ["design", "array", "prefix-sum"] }, + "304": { topicTags: ["design", "array", "matrix", "prefix-sum"] }, + "305": { topicTags: ["union-find", "array"] }, + "306": { topicTags: ["string", "backtracking"] }, + "307": { + topicTags: ["design", "binary-indexed-tree", "segment-tree", "array"], + }, + "308": { + topicTags: ["design", "binary-indexed-tree", "segment-tree", "array", "matrix"], + }, + "309": { topicTags: ["array", "dynamic-programming"] }, + "310": { + topicTags: ["depth-first-search", "breadth-first-search", "graph", "topological-sort"], + }, + "311": { topicTags: ["array", "hash-table", "matrix"] }, + "312": { topicTags: ["array", "dynamic-programming"] }, + "313": { topicTags: ["array", "math", "dynamic-programming"] }, + "314": { + topicTags: ["tree", "depth-first-search", "breadth-first-search", "hash-table", "binary-tree"], + }, + "315": { + topicTags: [ + "binary-indexed-tree", + "segment-tree", + "array", + "binary-search", + "divide-and-conquer", + "ordered-set", + "merge-sort", + ], + }, + "316": { topicTags: ["stack", "greedy", "string", "monotonic-stack"] }, + "317": { topicTags: ["breadth-first-search", "array", "matrix"] }, + "318": { topicTags: ["bit-manipulation", "array", "string"] }, + "319": { topicTags: ["brainteaser", "math"] }, + "320": { topicTags: ["bit-manipulation", "string", "backtracking"] }, + "321": { topicTags: ["stack", "greedy", "monotonic-stack"] }, + "322": { + topicTags: ["breadth-first-search", "array", "dynamic-programming"], + }, + "323": { + topicTags: ["depth-first-search", "breadth-first-search", "union-find", "graph"], + }, + "324": { + topicTags: ["array", "divide-and-conquer", "quickselect", "sorting"], + }, + "325": { topicTags: ["array", "hash-table"] }, + "326": { topicTags: ["recursion", "math"] }, + "327": { + topicTags: [ + "binary-indexed-tree", + "segment-tree", + "array", + "binary-search", + "divide-and-conquer", + "ordered-set", + "merge-sort", + ], + }, + "328": { topicTags: ["linked-list"] }, + "329": { + topicTags: [ + "depth-first-search", + "breadth-first-search", + "graph", + "topological-sort", + "memoization", + "array", + "dynamic-programming", + "matrix", + ], + }, + "330": { topicTags: ["greedy", "array"] }, + "331": { topicTags: ["stack", "tree", "string", "binary-tree"] }, + "332": { topicTags: ["depth-first-search", "graph", "eulerian-circuit"] }, + "333": { + topicTags: ["tree", "depth-first-search", "binary-search-tree", "dynamic-programming", "binary-tree"], + }, + "334": { topicTags: ["greedy", "array"] }, + "335": { topicTags: ["geometry", "array", "math"] }, + "336": { topicTags: ["trie", "array", "hash-table", "string"] }, + "337": { + topicTags: ["tree", "depth-first-search", "dynamic-programming", "binary-tree"], + }, + "338": { topicTags: ["bit-manipulation", "dynamic-programming"] }, + "339": { topicTags: ["depth-first-search", "breadth-first-search"] }, + "340": { topicTags: ["hash-table", "string", "sliding-window"] }, + "341": { + topicTags: ["stack", "tree", "depth-first-search", "design", "queue", "iterator"], + }, + "342": { topicTags: ["bit-manipulation", "recursion", "math"] }, + "343": { topicTags: ["math", "dynamic-programming"] }, + "344": { topicTags: ["recursion", "two-pointers", "string"] }, + "345": { topicTags: ["two-pointers", "string"] }, + "346": { topicTags: ["design", "queue", "array", "data-stream"] }, + "347": { + topicTags: [ + "array", + "hash-table", + "divide-and-conquer", + "bucket-sort", + "counting", + "quickselect", + "sorting", + "heap-priority-queue", + ], + }, + "348": { topicTags: ["design", "array", "hash-table", "matrix"] }, + "349": { + topicTags: ["array", "hash-table", "two-pointers", "binary-search", "sorting"], + }, + "350": { + topicTags: ["array", "hash-table", "two-pointers", "binary-search", "sorting"], + }, + "351": { topicTags: ["dynamic-programming", "backtracking"] }, + "352": { topicTags: ["design", "binary-search", "ordered-set"] }, + "353": { topicTags: ["design", "queue", "array", "matrix"] }, + "354": { + topicTags: ["array", "binary-search", "dynamic-programming", "sorting"], + }, + "355": { + topicTags: ["design", "hash-table", "linked-list", "heap-priority-queue"], + }, + "356": { topicTags: ["array", "hash-table", "math"] }, + "357": { topicTags: ["math", "dynamic-programming", "backtracking"] }, + "358": { + topicTags: ["greedy", "hash-table", "string", "counting", "sorting", "heap-priority-queue"], + }, + "359": { topicTags: ["design", "hash-table"] }, + "360": { topicTags: ["array", "math", "two-pointers", "sorting"] }, + "361": { topicTags: ["array", "dynamic-programming", "matrix"] }, + "362": { + topicTags: ["design", "queue", "array", "hash-table", "binary-search"], + }, + "363": { + topicTags: ["array", "binary-search", "matrix", "ordered-set", "prefix-sum"], + }, + "364": { + topicTags: ["stack", "depth-first-search", "breadth-first-search"], + }, + "365": { + topicTags: ["depth-first-search", "breadth-first-search", "math"], + }, + "366": { topicTags: ["tree", "depth-first-search", "binary-tree"] }, + "367": { topicTags: ["math", "binary-search"] }, + "368": { topicTags: ["array", "math", "dynamic-programming", "sorting"] }, + "369": { topicTags: ["linked-list", "math"] }, + "370": { topicTags: ["array", "prefix-sum"] }, + "371": { topicTags: ["bit-manipulation", "math"] }, + "372": { topicTags: ["math", "divide-and-conquer"] }, + "373": { topicTags: ["array", "heap-priority-queue"] }, + "374": { topicTags: ["binary-search", "interactive"] }, + "375": { topicTags: ["math", "dynamic-programming", "game-theory"] }, + "376": { topicTags: ["greedy", "array", "dynamic-programming"] }, + "377": { topicTags: ["array", "dynamic-programming"] }, + "378": { + topicTags: ["array", "binary-search", "matrix", "sorting", "heap-priority-queue"], + }, + "379": { + topicTags: ["design", "queue", "array", "hash-table", "linked-list"], + }, + "380": { + topicTags: ["design", "array", "hash-table", "math", "randomized"], + }, + "381": { + topicTags: ["design", "array", "hash-table", "math", "randomized"], + }, + "382": { + topicTags: ["reservoir-sampling", "linked-list", "math", "randomized"], + }, + "383": { topicTags: ["hash-table", "string", "counting"] }, + "384": { topicTags: ["array", "math", "randomized"] }, + "385": { topicTags: ["stack", "depth-first-search", "string"] }, + "386": { topicTags: ["depth-first-search", "trie"] }, + "387": { topicTags: ["queue", "hash-table", "string", "counting"] }, + "388": { topicTags: ["stack", "depth-first-search", "string"] }, + "389": { + topicTags: ["bit-manipulation", "hash-table", "string", "sorting"], + }, + "390": { topicTags: ["recursion", "math"] }, + "391": { topicTags: ["array", "line-sweep"] }, + "392": { topicTags: ["two-pointers", "string", "dynamic-programming"] }, + "393": { topicTags: ["bit-manipulation", "array"] }, + "394": { topicTags: ["stack", "recursion", "string"] }, + "395": { + topicTags: ["hash-table", "string", "divide-and-conquer", "sliding-window"], + }, + "396": { topicTags: ["array", "math", "dynamic-programming"] }, + "397": { + topicTags: ["greedy", "bit-manipulation", "memoization", "dynamic-programming"], + }, + "398": { + topicTags: ["reservoir-sampling", "hash-table", "math", "randomized"], + }, + "399": { + topicTags: ["depth-first-search", "breadth-first-search", "union-find", "graph", "array", "shortest-path"], + }, + "400": { topicTags: ["math", "binary-search"] }, + "401": { topicTags: ["bit-manipulation", "backtracking"] }, + "402": { topicTags: ["stack", "greedy", "string", "monotonic-stack"] }, + "403": { topicTags: ["array", "dynamic-programming"] }, + "404": { + topicTags: ["tree", "depth-first-search", "breadth-first-search", "binary-tree"], + }, + "405": { topicTags: ["bit-manipulation", "math"] }, + "406": { + topicTags: ["greedy", "binary-indexed-tree", "segment-tree", "array", "sorting"], + }, + "407": { + topicTags: ["breadth-first-search", "array", "matrix", "heap-priority-queue"], + }, + "408": { topicTags: ["two-pointers", "string"] }, + "409": { topicTags: ["greedy", "hash-table", "string"] }, + "410": { + topicTags: ["greedy", "array", "binary-search", "dynamic-programming"], + }, + "411": { topicTags: ["bit-manipulation", "string", "backtracking"] }, + "412": { topicTags: ["math", "string", "simulation"] }, + "413": { topicTags: ["array", "dynamic-programming"] }, + "414": { topicTags: ["array", "sorting"] }, + "415": { topicTags: ["math", "string", "simulation"] }, + "416": { topicTags: ["array", "dynamic-programming"] }, + "417": { + topicTags: ["depth-first-search", "breadth-first-search", "array", "matrix"], + }, + "418": { topicTags: ["string", "dynamic-programming", "simulation"] }, + "419": { topicTags: ["depth-first-search", "array", "matrix"] }, + "420": { topicTags: ["greedy", "string", "heap-priority-queue"] }, + "421": { topicTags: ["bit-manipulation", "trie", "array", "hash-table"] }, + "422": { topicTags: ["array", "matrix"] }, + "423": { topicTags: ["hash-table", "math", "string"] }, + "424": { topicTags: ["hash-table", "string", "sliding-window"] }, + "425": { topicTags: ["trie", "array", "string", "backtracking"] }, + "426": { + topicTags: [ + "stack", + "tree", + "depth-first-search", + "binary-search-tree", + "linked-list", + "binary-tree", + "doubly-linked-list", + ], + }, + "427": { topicTags: ["tree", "array", "divide-and-conquer", "matrix"] }, + "428": { + topicTags: ["tree", "depth-first-search", "breadth-first-search", "string"], + }, + "429": { topicTags: ["tree", "breadth-first-search"] }, + "430": { + topicTags: ["depth-first-search", "linked-list", "doubly-linked-list"], + }, + "431": { + topicTags: ["tree", "depth-first-search", "breadth-first-search", "design", "binary-tree"], + }, + "432": { + topicTags: ["design", "hash-table", "linked-list", "doubly-linked-list"], + }, + "433": { topicTags: ["breadth-first-search", "hash-table", "string"] }, + "434": { topicTags: ["string"] }, + "435": { topicTags: ["greedy", "array", "dynamic-programming", "sorting"] }, + "436": { topicTags: ["array", "binary-search", "sorting"] }, + "437": { topicTags: ["tree", "depth-first-search", "binary-tree"] }, + "438": { topicTags: ["hash-table", "string", "sliding-window"] }, + "439": { topicTags: ["stack", "recursion", "string"] }, + "440": { topicTags: ["trie"] }, + "441": { topicTags: ["math", "binary-search"] }, + "442": { topicTags: ["array", "hash-table"] }, + "443": { topicTags: ["two-pointers", "string"] }, + "444": { topicTags: ["graph", "topological-sort", "array"] }, + "445": { topicTags: ["stack", "linked-list", "math"] }, + "446": { topicTags: ["array", "dynamic-programming"] }, + "447": { topicTags: ["array", "hash-table", "math"] }, + "448": { topicTags: ["array", "hash-table"] }, + "449": { + topicTags: [ + "tree", + "depth-first-search", + "breadth-first-search", + "design", + "binary-search-tree", + "string", + "binary-tree", + ], + }, + "450": { topicTags: ["tree", "binary-search-tree", "binary-tree"] }, + "451": { + topicTags: ["hash-table", "string", "bucket-sort", "counting", "sorting", "heap-priority-queue"], + }, + "452": { topicTags: ["greedy", "array", "sorting"] }, + "453": { topicTags: ["array", "math"] }, + "454": { topicTags: ["array", "hash-table"] }, + "455": { topicTags: ["greedy", "array", "two-pointers", "sorting"] }, + "456": { + topicTags: ["stack", "array", "binary-search", "ordered-set", "monotonic-stack"], + }, + "457": { topicTags: ["array", "hash-table", "two-pointers"] }, + "458": { topicTags: ["math", "dynamic-programming", "combinatorics"] }, + "459": { topicTags: ["string", "string-matching"] }, + "460": { + topicTags: ["design", "hash-table", "linked-list", "doubly-linked-list"], + }, + "461": { topicTags: ["bit-manipulation"] }, + "462": { topicTags: ["array", "math", "sorting"] }, + "463": { + topicTags: ["depth-first-search", "breadth-first-search", "array", "matrix"], + }, + "464": { + topicTags: ["bit-manipulation", "memoization", "math", "dynamic-programming", "bitmask", "game-theory"], + }, + "465": { + topicTags: ["bit-manipulation", "array", "dynamic-programming", "backtracking", "bitmask"], + }, + "466": { topicTags: ["string", "dynamic-programming"] }, + "467": { topicTags: ["string", "dynamic-programming"] }, + "468": { topicTags: ["string"] }, + "469": { topicTags: ["geometry", "math"] }, + "470": { + topicTags: ["math", "rejection-sampling", "probability-and-statistics", "randomized"], + }, + "471": { topicTags: ["string", "dynamic-programming"] }, + "472": { + topicTags: ["depth-first-search", "trie", "array", "string", "dynamic-programming"], + }, + "473": { + topicTags: ["bit-manipulation", "array", "dynamic-programming", "backtracking", "bitmask"], + }, + "474": { topicTags: ["array", "string", "dynamic-programming"] }, + "475": { topicTags: ["array", "two-pointers", "binary-search", "sorting"] }, + "476": { topicTags: ["bit-manipulation"] }, + "477": { topicTags: ["bit-manipulation", "array", "math"] }, + "478": { + topicTags: ["geometry", "math", "rejection-sampling", "randomized"], + }, + "479": { topicTags: ["math"] }, + "480": { + topicTags: ["array", "hash-table", "sliding-window", "heap-priority-queue"], + }, + "481": { topicTags: ["two-pointers", "string"] }, + "482": { topicTags: ["string"] }, + "483": { topicTags: ["math", "binary-search"] }, + "484": { topicTags: ["stack", "greedy", "array", "string"] }, + "485": { topicTags: ["array"] }, + "486": { + topicTags: ["recursion", "array", "math", "dynamic-programming", "game-theory"], + }, + "487": { topicTags: ["array", "dynamic-programming", "sliding-window"] }, + "488": { + topicTags: ["breadth-first-search", "memoization", "string", "dynamic-programming"], + }, + "489": { topicTags: ["backtracking", "interactive"] }, + "490": { + topicTags: ["depth-first-search", "breadth-first-search", "graph"], + }, + "491": { + topicTags: ["bit-manipulation", "array", "hash-table", "backtracking"], + }, + "492": { topicTags: ["math"] }, + "493": { + topicTags: [ + "binary-indexed-tree", + "segment-tree", + "array", + "binary-search", + "divide-and-conquer", + "ordered-set", + "merge-sort", + ], + }, + "494": { topicTags: ["array", "dynamic-programming", "backtracking"] }, + "495": { topicTags: ["array", "simulation"] }, + "496": { topicTags: ["stack", "array", "hash-table", "monotonic-stack"] }, + "497": { + topicTags: ["reservoir-sampling", "math", "binary-search", "ordered-set", "prefix-sum", "randomized"], + }, + "498": { topicTags: ["array", "matrix", "simulation"] }, + "499": { + topicTags: ["depth-first-search", "breadth-first-search", "graph", "shortest-path", "heap-priority-queue"], + }, + "500": { topicTags: ["array", "hash-table", "string"] }, + "501": { + topicTags: ["tree", "depth-first-search", "binary-search-tree", "binary-tree"], + }, + "502": { topicTags: ["greedy", "array", "sorting", "heap-priority-queue"] }, + "503": { topicTags: ["stack", "array", "monotonic-stack"] }, + "504": { topicTags: ["math"] }, + "505": { + topicTags: ["depth-first-search", "breadth-first-search", "graph", "shortest-path", "heap-priority-queue"], + }, + "506": { topicTags: ["array", "sorting", "heap-priority-queue"] }, + "507": { topicTags: ["math"] }, + "508": { + topicTags: ["tree", "depth-first-search", "hash-table", "binary-tree"], + }, + "509": { + topicTags: ["recursion", "memoization", "math", "dynamic-programming"], + }, + "510": { topicTags: ["tree", "binary-search-tree", "binary-tree"] }, + "511": { topicTags: ["database"] }, + "512": { topicTags: ["database"] }, + "513": { + topicTags: ["tree", "depth-first-search", "breadth-first-search", "binary-tree"], + }, + "514": { + topicTags: ["depth-first-search", "breadth-first-search", "string", "dynamic-programming"], + }, + "515": { + topicTags: ["tree", "depth-first-search", "breadth-first-search", "binary-tree"], + }, + "516": { topicTags: ["string", "dynamic-programming"] }, + "517": { topicTags: ["greedy", "array"] }, + "518": { topicTags: ["array", "dynamic-programming"] }, + "519": { + topicTags: ["reservoir-sampling", "hash-table", "math", "randomized"], + }, + "520": { topicTags: ["string"] }, + "521": { topicTags: ["string"] }, + "522": { + topicTags: ["array", "hash-table", "two-pointers", "string", "sorting"], + }, + "523": { topicTags: ["array", "hash-table", "math", "prefix-sum"] }, + "524": { topicTags: ["array", "two-pointers", "string", "sorting"] }, + "525": { topicTags: ["array", "hash-table", "prefix-sum"] }, + "526": { + topicTags: ["bit-manipulation", "array", "dynamic-programming", "backtracking", "bitmask"], + }, + "527": { topicTags: ["greedy", "trie", "array", "string", "sorting"] }, + "528": { topicTags: ["math", "binary-search", "prefix-sum", "randomized"] }, + "529": { + topicTags: ["depth-first-search", "breadth-first-search", "array", "matrix"], + }, + "530": { + topicTags: ["tree", "depth-first-search", "breadth-first-search", "binary-search-tree", "binary-tree"], + }, + "531": { topicTags: ["array", "hash-table", "matrix"] }, + "532": { + topicTags: ["array", "hash-table", "two-pointers", "binary-search", "sorting"], + }, + "533": { topicTags: ["array", "hash-table", "matrix"] }, + "534": { topicTags: ["database"] }, + "535": { topicTags: ["design", "hash-table", "string", "hash-function"] }, + "536": { + topicTags: ["tree", "depth-first-search", "string", "binary-tree"], + }, + "537": { topicTags: ["math", "string", "simulation"] }, + "538": { + topicTags: ["tree", "depth-first-search", "binary-search-tree", "binary-tree"], + }, + "539": { topicTags: ["array", "math", "string", "sorting"] }, + "540": { topicTags: ["array", "binary-search"] }, + "541": { topicTags: ["two-pointers", "string"] }, + "542": { + topicTags: ["breadth-first-search", "array", "dynamic-programming", "matrix"], + }, + "543": { topicTags: ["tree", "depth-first-search", "binary-tree"] }, + "544": { topicTags: ["recursion", "string", "simulation"] }, + "545": { topicTags: ["tree", "depth-first-search", "binary-tree"] }, + "546": { topicTags: ["memoization", "array", "dynamic-programming"] }, + "547": { + topicTags: ["depth-first-search", "breadth-first-search", "union-find", "graph"], + }, + "548": { topicTags: ["array", "prefix-sum"] }, + "549": { topicTags: ["tree", "depth-first-search", "binary-tree"] }, + "550": { topicTags: ["database"] }, + "551": { topicTags: ["string"] }, + "552": { topicTags: ["dynamic-programming"] }, + "553": { topicTags: ["array", "math", "dynamic-programming"] }, + "554": { topicTags: ["array", "hash-table"] }, + "555": { topicTags: ["greedy", "array", "string"] }, + "556": { topicTags: ["math", "two-pointers", "string"] }, + "557": { topicTags: ["two-pointers", "string"] }, + "558": { topicTags: ["tree", "divide-and-conquer"] }, + "559": { + topicTags: ["tree", "depth-first-search", "breadth-first-search"], + }, + "560": { topicTags: ["array", "hash-table", "prefix-sum"] }, + "561": { topicTags: ["greedy", "array", "counting-sort", "sorting"] }, + "562": { topicTags: ["array", "dynamic-programming", "matrix"] }, + "563": { topicTags: ["tree", "depth-first-search", "binary-tree"] }, + "564": { topicTags: ["math", "string"] }, + "565": { topicTags: ["depth-first-search", "array"] }, + "566": { topicTags: ["array", "matrix", "simulation"] }, + "567": { + topicTags: ["hash-table", "two-pointers", "string", "sliding-window"], + }, + "568": { topicTags: ["array", "dynamic-programming", "matrix"] }, + "569": { topicTags: ["database"] }, + "570": { topicTags: ["database"] }, + "571": { topicTags: ["database"] }, + "572": { + topicTags: ["tree", "depth-first-search", "binary-tree", "string-matching", "hash-function"], + }, + "573": { topicTags: ["array", "math"] }, + "574": { topicTags: ["database"] }, + "575": { topicTags: ["array", "hash-table"] }, + "576": { topicTags: ["dynamic-programming"] }, + "577": { topicTags: ["database"] }, + "578": { topicTags: ["database"] }, + "579": { topicTags: ["database"] }, + "580": { topicTags: ["database"] }, + "581": { + topicTags: ["stack", "greedy", "array", "two-pointers", "sorting", "monotonic-stack"], + }, + "582": { + topicTags: ["tree", "depth-first-search", "breadth-first-search", "array", "hash-table"], + }, + "583": { topicTags: ["string", "dynamic-programming"] }, + "584": { topicTags: ["database"] }, + "585": { topicTags: ["database"] }, + "586": { topicTags: ["database"] }, + "587": { topicTags: ["geometry", "array", "math"] }, + "588": { topicTags: ["design", "trie", "hash-table", "string"] }, + "589": { topicTags: ["stack", "tree", "depth-first-search"] }, + "590": { topicTags: ["stack", "tree", "depth-first-search"] }, + "591": { topicTags: ["stack", "string"] }, + "592": { topicTags: ["math", "string", "simulation"] }, + "593": { topicTags: ["geometry", "math"] }, + "594": { topicTags: ["array", "hash-table", "sorting"] }, + "595": { topicTags: ["database"] }, + "596": { topicTags: ["database"] }, + "597": { topicTags: ["database"] }, + "598": { topicTags: ["array", "math"] }, + "599": { topicTags: ["array", "hash-table", "string"] }, + "600": { topicTags: ["dynamic-programming"] }, + "601": { topicTags: ["database"] }, + "602": { topicTags: ["database"] }, + "603": { topicTags: ["database"] }, + "604": { + topicTags: ["design", "array", "hash-table", "string", "iterator"], + }, + "605": { topicTags: ["greedy", "array"] }, + "606": { + topicTags: ["tree", "depth-first-search", "string", "binary-tree"], + }, + "607": { topicTags: ["database"] }, + "608": { topicTags: ["database"] }, + "609": { topicTags: ["array", "hash-table", "string"] }, + "610": { topicTags: ["database"] }, + "611": { + topicTags: ["greedy", "array", "two-pointers", "binary-search", "sorting"], + }, + "612": { topicTags: ["database"] }, + "613": { topicTags: ["database"] }, + "614": { topicTags: ["database"] }, + "615": { topicTags: ["database"] }, + "616": { + topicTags: ["trie", "array", "hash-table", "string", "string-matching"], + }, + "617": { + topicTags: ["tree", "depth-first-search", "breadth-first-search", "binary-tree"], + }, + "618": { topicTags: ["database"] }, + "619": { topicTags: ["database"] }, + "620": { topicTags: ["database"] }, + "621": { + topicTags: ["greedy", "array", "hash-table", "counting", "sorting", "heap-priority-queue"], + }, + "622": { topicTags: ["design", "queue", "array", "linked-list"] }, + "623": { + topicTags: ["tree", "depth-first-search", "breadth-first-search", "binary-tree"], + }, + "624": { topicTags: ["greedy", "array"] }, + "625": { topicTags: ["greedy", "math"] }, + "626": { topicTags: ["database"] }, + "627": { topicTags: ["database"] }, + "628": { topicTags: ["array", "math", "sorting"] }, + "629": { topicTags: ["dynamic-programming"] }, + "630": { topicTags: ["greedy", "array", "heap-priority-queue"] }, + "631": { topicTags: ["graph", "design", "topological-sort"] }, + "632": { + topicTags: ["greedy", "array", "hash-table", "sorting", "sliding-window", "heap-priority-queue"], + }, + "633": { topicTags: ["math", "two-pointers", "binary-search"] }, + "634": { topicTags: ["math", "dynamic-programming"] }, + "635": { topicTags: ["design", "hash-table", "string", "ordered-set"] }, + "636": { topicTags: ["stack", "array"] }, + "637": { + topicTags: ["tree", "depth-first-search", "breadth-first-search", "binary-tree"], + }, + "638": { + topicTags: ["bit-manipulation", "memoization", "array", "dynamic-programming", "backtracking", "bitmask"], + }, + "639": { topicTags: ["string", "dynamic-programming"] }, + "640": { topicTags: ["math", "string", "simulation"] }, + "641": { topicTags: ["design", "queue", "array", "linked-list"] }, + "642": { topicTags: ["design", "trie", "string", "data-stream"] }, + "643": { topicTags: ["array", "sliding-window"] }, + "644": { topicTags: ["array", "binary-search", "prefix-sum"] }, + "645": { + topicTags: ["bit-manipulation", "array", "hash-table", "sorting"], + }, + "646": { topicTags: ["greedy", "array", "dynamic-programming", "sorting"] }, + "647": { topicTags: ["string", "dynamic-programming"] }, + "648": { topicTags: ["trie", "array", "hash-table", "string"] }, + "649": { topicTags: ["greedy", "queue", "string"] }, + "650": { topicTags: ["math", "dynamic-programming"] }, + "651": { topicTags: ["math", "dynamic-programming"] }, + "652": { + topicTags: ["tree", "depth-first-search", "hash-table", "binary-tree"], + }, + "653": { + topicTags: [ + "tree", + "depth-first-search", + "breadth-first-search", + "binary-search-tree", + "hash-table", + "two-pointers", + "binary-tree", + ], + }, + "654": { + topicTags: ["stack", "tree", "array", "divide-and-conquer", "binary-tree", "monotonic-stack"], + }, + "655": { + topicTags: ["tree", "depth-first-search", "breadth-first-search", "binary-tree"], + }, + "656": { topicTags: ["array", "dynamic-programming"] }, + "657": { topicTags: ["string", "simulation"] }, + "658": { + topicTags: ["array", "two-pointers", "binary-search", "sorting", "heap-priority-queue"], + }, + "659": { + topicTags: ["greedy", "array", "hash-table", "heap-priority-queue"], + }, + "660": { topicTags: ["math"] }, + "661": { topicTags: ["array", "matrix"] }, + "662": { + topicTags: ["tree", "depth-first-search", "breadth-first-search", "binary-tree"], + }, + "663": { topicTags: ["tree", "depth-first-search", "binary-tree"] }, + "664": { topicTags: ["string", "dynamic-programming"] }, + "665": { topicTags: ["array"] }, + "666": { + topicTags: ["tree", "depth-first-search", "array", "binary-tree"], + }, + "667": { topicTags: ["array", "math"] }, + "668": { topicTags: ["math", "binary-search"] }, + "669": { + topicTags: ["tree", "depth-first-search", "binary-search-tree", "binary-tree"], + }, + "670": { topicTags: ["greedy", "math"] }, + "671": { topicTags: ["tree", "depth-first-search", "binary-tree"] }, + "672": { + topicTags: ["bit-manipulation", "depth-first-search", "breadth-first-search", "math"], + }, + "673": { + topicTags: ["binary-indexed-tree", "segment-tree", "array", "dynamic-programming"], + }, + "674": { topicTags: ["array"] }, + "675": { + topicTags: ["breadth-first-search", "array", "matrix", "heap-priority-queue"], + }, + "676": { topicTags: ["design", "trie", "hash-table", "string"] }, + "677": { topicTags: ["design", "trie", "hash-table", "string"] }, + "678": { topicTags: ["stack", "greedy", "string", "dynamic-programming"] }, + "679": { topicTags: ["array", "math", "backtracking"] }, + "680": { topicTags: ["greedy", "two-pointers", "string"] }, + "681": { topicTags: ["string", "enumeration"] }, + "682": { topicTags: ["stack", "array", "simulation"] }, + "683": { + topicTags: ["binary-indexed-tree", "array", "ordered-set", "sliding-window"], + }, + "684": { + topicTags: ["depth-first-search", "breadth-first-search", "union-find", "graph"], + }, + "685": { + topicTags: ["depth-first-search", "breadth-first-search", "union-find", "graph"], + }, + "686": { topicTags: ["string", "string-matching"] }, + "687": { topicTags: ["tree", "depth-first-search", "binary-tree"] }, + "688": { topicTags: ["dynamic-programming"] }, + "689": { topicTags: ["array", "dynamic-programming"] }, + "690": { + topicTags: ["depth-first-search", "breadth-first-search", "hash-table"], + }, + "691": { + topicTags: ["bit-manipulation", "array", "string", "dynamic-programming", "backtracking", "bitmask"], + }, + "692": { + topicTags: ["trie", "hash-table", "string", "bucket-sort", "counting", "sorting", "heap-priority-queue"], + }, + "693": { topicTags: ["bit-manipulation"] }, + "694": { + topicTags: ["depth-first-search", "breadth-first-search", "union-find", "hash-table", "hash-function"], + }, + "695": { + topicTags: ["depth-first-search", "breadth-first-search", "union-find", "array", "matrix"], + }, + "696": { topicTags: ["two-pointers", "string"] }, + "697": { topicTags: ["array", "hash-table"] }, + "698": { + topicTags: ["bit-manipulation", "memoization", "array", "dynamic-programming", "backtracking", "bitmask"], + }, + "699": { topicTags: ["segment-tree", "array", "ordered-set"] }, + "700": { topicTags: ["tree", "binary-search-tree", "binary-tree"] }, + "701": { topicTags: ["tree", "binary-search-tree", "binary-tree"] }, + "702": { topicTags: ["array", "binary-search", "interactive"] }, + "703": { + topicTags: ["tree", "design", "binary-search-tree", "binary-tree", "data-stream", "heap-priority-queue"], + }, + "704": { topicTags: ["array", "binary-search"] }, + "705": { + topicTags: ["design", "array", "hash-table", "linked-list", "hash-function"], + }, + "706": { + topicTags: ["design", "array", "hash-table", "linked-list", "hash-function"], + }, + "707": { topicTags: ["design", "linked-list"] }, + "708": { topicTags: ["linked-list"] }, + "709": { topicTags: ["string"] }, + "710": { + topicTags: ["hash-table", "math", "binary-search", "sorting", "randomized"], + }, + "711": { + topicTags: ["depth-first-search", "breadth-first-search", "union-find", "hash-table", "hash-function"], + }, + "712": { topicTags: ["string", "dynamic-programming"] }, + "713": { topicTags: ["array", "sliding-window"] }, + "714": { topicTags: ["greedy", "array", "dynamic-programming"] }, + "715": { topicTags: ["design", "segment-tree", "ordered-set"] }, + "716": { + topicTags: ["stack", "design", "linked-list", "doubly-linked-list", "ordered-set"], + }, + "717": { topicTags: ["array"] }, + "718": { + topicTags: ["array", "binary-search", "dynamic-programming", "sliding-window", "hash-function", "rolling-hash"], + }, + "719": { topicTags: ["array", "two-pointers", "binary-search", "sorting"] }, + "720": { topicTags: ["trie", "array", "hash-table", "string", "sorting"] }, + "721": { + topicTags: ["depth-first-search", "breadth-first-search", "union-find", "array", "string"], + }, + "722": { topicTags: ["array", "string"] }, + "723": { topicTags: ["array", "two-pointers", "matrix", "simulation"] }, + "724": { topicTags: ["array", "prefix-sum"] }, + "725": { topicTags: ["linked-list"] }, + "726": { topicTags: ["stack", "hash-table", "string", "sorting"] }, + "727": { topicTags: ["string", "dynamic-programming", "sliding-window"] }, + "728": { topicTags: ["math"] }, + "729": { + topicTags: ["design", "segment-tree", "binary-search", "ordered-set"], + }, + "730": { topicTags: ["string", "dynamic-programming"] }, + "731": { + topicTags: ["design", "segment-tree", "binary-search", "ordered-set"], + }, + "732": { + topicTags: ["design", "segment-tree", "binary-search", "ordered-set"], + }, + "733": { + topicTags: ["depth-first-search", "breadth-first-search", "array", "matrix"], + }, + "734": { topicTags: ["array", "hash-table", "string"] }, + "735": { topicTags: ["stack", "array"] }, + "736": { topicTags: ["stack", "recursion", "hash-table", "string"] }, + "737": { + topicTags: ["depth-first-search", "breadth-first-search", "union-find", "array", "hash-table", "string"], + }, + "738": { topicTags: ["greedy", "math"] }, + "739": { topicTags: ["stack", "array", "monotonic-stack"] }, + "740": { topicTags: ["array", "hash-table", "dynamic-programming"] }, + "741": { topicTags: ["array", "dynamic-programming", "matrix"] }, + "742": { + topicTags: ["tree", "depth-first-search", "breadth-first-search", "binary-tree"], + }, + "743": { + topicTags: ["depth-first-search", "breadth-first-search", "graph", "shortest-path", "heap-priority-queue"], + }, + "744": { topicTags: ["array", "binary-search"] }, + "745": { topicTags: ["design", "trie", "hash-table", "string"] }, + "746": { topicTags: ["array", "dynamic-programming"] }, + "747": { topicTags: ["array", "sorting"] }, + "748": { topicTags: ["array", "hash-table", "string"] }, + "749": { + topicTags: ["depth-first-search", "breadth-first-search", "array", "matrix", "simulation"], + }, + "750": { topicTags: ["array", "math", "dynamic-programming", "matrix"] }, + "751": { topicTags: ["bit-manipulation", "string"] }, + "752": { + topicTags: ["breadth-first-search", "array", "hash-table", "string"], + }, + "753": { topicTags: ["depth-first-search", "graph", "eulerian-circuit"] }, + "754": { topicTags: ["math", "binary-search"] }, + "755": { topicTags: ["array", "simulation"] }, + "756": { + topicTags: ["bit-manipulation", "depth-first-search", "breadth-first-search"], + }, + "757": { topicTags: ["greedy", "array", "sorting"] }, + "758": { + topicTags: ["trie", "array", "hash-table", "string", "string-matching"], + }, + "759": { topicTags: ["array", "sorting", "heap-priority-queue"] }, + "760": { topicTags: ["array", "hash-table"] }, + "761": { topicTags: ["recursion", "string"] }, + "762": { topicTags: ["bit-manipulation", "math"] }, + "763": { topicTags: ["greedy", "hash-table", "two-pointers", "string"] }, + "764": { topicTags: ["array", "dynamic-programming"] }, + "765": { + topicTags: ["greedy", "depth-first-search", "breadth-first-search", "union-find", "graph"], + }, + "766": { topicTags: ["array", "matrix"] }, + "767": { + topicTags: ["greedy", "hash-table", "string", "counting", "sorting", "heap-priority-queue"], + }, + "768": { + topicTags: ["stack", "greedy", "array", "sorting", "monotonic-stack"], + }, + "769": { + topicTags: ["stack", "greedy", "array", "sorting", "monotonic-stack"], + }, + "770": { + topicTags: ["stack", "recursion", "hash-table", "math", "string"], + }, + "771": { topicTags: ["hash-table", "string"] }, + "772": { topicTags: ["stack", "recursion", "math", "string"] }, + "773": { topicTags: ["breadth-first-search", "array", "matrix"] }, + "774": { topicTags: ["array", "binary-search"] }, + "775": { topicTags: ["array", "math"] }, + "776": { + topicTags: ["tree", "binary-search-tree", "recursion", "binary-tree"], + }, + "777": { topicTags: ["two-pointers", "string"] }, + "778": { + topicTags: [ + "depth-first-search", + "breadth-first-search", + "union-find", + "array", + "binary-search", + "matrix", + "heap-priority-queue", + ], + }, + "779": { topicTags: ["bit-manipulation", "recursion", "math"] }, + "780": { topicTags: ["math"] }, + "781": { topicTags: ["greedy", "array", "hash-table", "math"] }, + "782": { topicTags: ["bit-manipulation", "array", "math", "matrix"] }, + "783": { + topicTags: ["tree", "depth-first-search", "breadth-first-search", "binary-search-tree", "binary-tree"], + }, + "784": { topicTags: ["bit-manipulation", "string", "backtracking"] }, + "785": { + topicTags: ["depth-first-search", "breadth-first-search", "union-find", "graph"], + }, + "786": { + topicTags: ["array", "binary-search", "sorting", "heap-priority-queue"], + }, + "787": { + topicTags: [ + "depth-first-search", + "breadth-first-search", + "graph", + "dynamic-programming", + "shortest-path", + "heap-priority-queue", + ], + }, + "788": { topicTags: ["math", "dynamic-programming"] }, + "789": { topicTags: ["array", "math"] }, + "790": { topicTags: ["dynamic-programming"] }, + "791": { topicTags: ["hash-table", "string", "sorting"] }, + "792": { topicTags: ["trie", "hash-table", "string", "sorting"] }, + "793": { topicTags: ["math", "binary-search"] }, + "794": { topicTags: ["array", "string"] }, + "795": { topicTags: ["array", "two-pointers"] }, + "796": { topicTags: ["string", "string-matching"] }, + "797": { + topicTags: ["depth-first-search", "breadth-first-search", "graph", "backtracking"], + }, + "798": { topicTags: ["array", "prefix-sum"] }, + "799": { topicTags: ["dynamic-programming"] }, + "800": { topicTags: ["math", "string", "enumeration"] }, + "801": { topicTags: ["array", "dynamic-programming"] }, + "802": { + topicTags: ["depth-first-search", "breadth-first-search", "graph", "topological-sort"], + }, + "803": { topicTags: ["union-find", "array", "matrix"] }, + "804": { topicTags: ["array", "hash-table", "string"] }, + "805": { + topicTags: ["bit-manipulation", "array", "math", "dynamic-programming", "bitmask"], + }, + "806": { topicTags: ["array", "string"] }, + "807": { topicTags: ["greedy", "array", "matrix"] }, + "808": { + topicTags: ["math", "dynamic-programming", "probability-and-statistics"], + }, + "809": { topicTags: ["array", "two-pointers", "string"] }, + "810": { + topicTags: ["bit-manipulation", "brainteaser", "array", "math", "game-theory"], + }, + "811": { topicTags: ["array", "hash-table", "string", "counting"] }, + "812": { topicTags: ["geometry", "array", "math"] }, + "813": { topicTags: ["array", "dynamic-programming"] }, + "814": { topicTags: ["tree", "depth-first-search", "binary-tree"] }, + "815": { topicTags: ["breadth-first-search", "array", "hash-table"] }, + "816": { topicTags: ["string", "backtracking"] }, + "817": { topicTags: ["array", "hash-table", "linked-list"] }, + "818": { topicTags: ["dynamic-programming"] }, + "819": { topicTags: ["hash-table", "string", "counting"] }, + "820": { topicTags: ["trie", "array", "hash-table", "string"] }, + "821": { topicTags: ["array", "two-pointers", "string"] }, + "822": { topicTags: ["array", "hash-table"] }, + "823": { topicTags: ["array", "hash-table", "dynamic-programming"] }, + "824": { topicTags: ["string"] }, + "825": { topicTags: ["array", "two-pointers", "binary-search", "sorting"] }, + "826": { + topicTags: ["greedy", "array", "two-pointers", "binary-search", "sorting"], + }, + "827": { + topicTags: ["depth-first-search", "breadth-first-search", "union-find", "array", "matrix"], + }, + "828": { topicTags: ["hash-table", "string", "dynamic-programming"] }, + "829": { topicTags: ["math", "enumeration"] }, + "830": { topicTags: ["string"] }, + "831": { topicTags: ["string"] }, + "832": { topicTags: ["array", "two-pointers", "matrix", "simulation"] }, + "833": { topicTags: ["array", "string", "sorting"] }, + "834": { + topicTags: ["tree", "depth-first-search", "graph", "dynamic-programming"], + }, + "835": { topicTags: ["array", "matrix"] }, + "836": { topicTags: ["geometry", "math"] }, + "837": { + topicTags: ["math", "dynamic-programming", "sliding-window", "probability-and-statistics"], + }, + "838": { topicTags: ["two-pointers", "string", "dynamic-programming"] }, + "839": { + topicTags: ["depth-first-search", "breadth-first-search", "union-find", "array", "string"], + }, + "840": { topicTags: ["array", "math", "matrix"] }, + "841": { + topicTags: ["depth-first-search", "breadth-first-search", "graph"], + }, + "842": { topicTags: ["string", "backtracking"] }, + "843": { + topicTags: ["array", "math", "string", "game-theory", "interactive"], + }, + "844": { topicTags: ["stack", "two-pointers", "string", "simulation"] }, + "845": { + topicTags: ["array", "two-pointers", "dynamic-programming", "enumeration"], + }, + "846": { topicTags: ["greedy", "array", "hash-table", "sorting"] }, + "847": { + topicTags: ["bit-manipulation", "breadth-first-search", "graph", "dynamic-programming", "bitmask"], + }, + "848": { topicTags: ["array", "string"] }, + "849": { topicTags: ["array"] }, + "850": { + topicTags: ["segment-tree", "array", "ordered-set", "line-sweep"], + }, + "851": { + topicTags: ["depth-first-search", "graph", "topological-sort", "array"], + }, + "852": { topicTags: ["array", "binary-search"] }, + "853": { topicTags: ["stack", "array", "sorting", "monotonic-stack"] }, + "854": { topicTags: ["breadth-first-search", "string"] }, + "855": { topicTags: ["design", "ordered-set"] }, + "856": { topicTags: ["stack", "string"] }, + "857": { topicTags: ["greedy", "array", "sorting", "heap-priority-queue"] }, + "858": { topicTags: ["geometry", "math"] }, + "859": { topicTags: ["hash-table", "string"] }, + "860": { topicTags: ["greedy", "array"] }, + "861": { topicTags: ["greedy", "bit-manipulation", "array", "matrix"] }, + "862": { + topicTags: [ + "queue", + "array", + "binary-search", + "prefix-sum", + "sliding-window", + "monotonic-queue", + "heap-priority-queue", + ], + }, + "863": { + topicTags: ["tree", "depth-first-search", "breadth-first-search", "binary-tree"], + }, + "864": { topicTags: ["bit-manipulation", "breadth-first-search"] }, + "865": { + topicTags: ["tree", "depth-first-search", "breadth-first-search", "hash-table", "binary-tree"], + }, + "866": { topicTags: ["math"] }, + "867": { topicTags: ["array", "matrix", "simulation"] }, + "868": { topicTags: ["bit-manipulation"] }, + "869": { topicTags: ["math", "counting", "enumeration", "sorting"] }, + "870": { topicTags: ["greedy", "array", "two-pointers", "sorting"] }, + "871": { + topicTags: ["greedy", "array", "dynamic-programming", "heap-priority-queue"], + }, + "872": { topicTags: ["tree", "depth-first-search", "binary-tree"] }, + "873": { topicTags: ["array", "hash-table", "dynamic-programming"] }, + "874": { topicTags: ["array", "simulation"] }, + "875": { topicTags: ["array", "binary-search"] }, + "876": { topicTags: ["linked-list", "two-pointers"] }, + "877": { + topicTags: ["array", "math", "dynamic-programming", "game-theory"], + }, + "878": { topicTags: ["math", "binary-search"] }, + "879": { topicTags: ["array", "dynamic-programming"] }, + "880": { topicTags: ["stack", "string"] }, + "881": { topicTags: ["greedy", "array", "two-pointers", "sorting"] }, + "882": { topicTags: ["graph", "shortest-path", "heap-priority-queue"] }, + "883": { topicTags: ["geometry", "array", "math", "matrix"] }, + "884": { topicTags: ["hash-table", "string"] }, + "885": { topicTags: ["array", "matrix", "simulation"] }, + "886": { + topicTags: ["depth-first-search", "breadth-first-search", "union-find", "graph"], + }, + "887": { topicTags: ["math", "binary-search", "dynamic-programming"] }, + "888": { topicTags: ["array", "hash-table", "binary-search", "sorting"] }, + "889": { + topicTags: ["tree", "array", "hash-table", "divide-and-conquer", "binary-tree"], + }, + "890": { topicTags: ["array", "hash-table", "string"] }, + "891": { topicTags: ["array", "math", "sorting"] }, + "892": { topicTags: ["geometry", "array", "math", "matrix"] }, + "893": { topicTags: ["array", "hash-table", "string"] }, + "894": { + topicTags: ["tree", "recursion", "memoization", "dynamic-programming", "binary-tree"], + }, + "895": { topicTags: ["stack", "design", "hash-table", "ordered-set"] }, + "896": { topicTags: ["array"] }, + "897": { + topicTags: ["stack", "tree", "depth-first-search", "binary-search-tree", "binary-tree"], + }, + "898": { topicTags: ["bit-manipulation", "array", "dynamic-programming"] }, + "899": { topicTags: ["math", "string", "sorting"] }, + "900": { topicTags: ["design", "array", "counting", "iterator"] }, + "901": { topicTags: ["stack", "design", "data-stream", "monotonic-stack"] }, + "902": { + topicTags: ["array", "math", "string", "binary-search", "dynamic-programming"], + }, + "903": { topicTags: ["dynamic-programming"] }, + "904": { topicTags: ["array", "hash-table", "sliding-window"] }, + "905": { topicTags: ["array", "two-pointers", "sorting"] }, + "906": { topicTags: ["math", "enumeration"] }, + "907": { + topicTags: ["stack", "array", "dynamic-programming", "monotonic-stack"], + }, + "908": { topicTags: ["array", "math"] }, + "909": { topicTags: ["breadth-first-search", "array", "matrix"] }, + "910": { topicTags: ["greedy", "array", "math", "sorting"] }, + "911": { topicTags: ["design", "array", "hash-table", "binary-search"] }, + "912": { + topicTags: [ + "array", + "divide-and-conquer", + "bucket-sort", + "counting-sort", + "radix-sort", + "sorting", + "heap-priority-queue", + "merge-sort", + ], + }, + "913": { + topicTags: ["graph", "topological-sort", "memoization", "math", "dynamic-programming", "game-theory"], + }, + "914": { + topicTags: ["array", "hash-table", "math", "counting", "number-theory"], + }, + "915": { topicTags: ["array"] }, + "916": { topicTags: ["array", "hash-table", "string"] }, + "917": { topicTags: ["two-pointers", "string"] }, + "918": { + topicTags: ["queue", "array", "divide-and-conquer", "dynamic-programming", "monotonic-queue"], + }, + "919": { + topicTags: ["tree", "breadth-first-search", "design", "binary-tree"], + }, + "920": { topicTags: ["math", "dynamic-programming", "combinatorics"] }, + "921": { topicTags: ["stack", "greedy", "string"] }, + "922": { topicTags: ["array", "two-pointers", "sorting"] }, + "923": { + topicTags: ["array", "hash-table", "two-pointers", "counting", "sorting"], + }, + "924": { + topicTags: ["depth-first-search", "breadth-first-search", "union-find", "array", "matrix"], + }, + "925": { topicTags: ["two-pointers", "string"] }, + "926": { topicTags: ["string", "dynamic-programming"] }, + "927": { topicTags: ["array", "math"] }, + "928": { + topicTags: ["depth-first-search", "breadth-first-search", "union-find", "array", "matrix"], + }, + "929": { topicTags: ["array", "hash-table", "string"] }, + "930": { + topicTags: ["array", "hash-table", "prefix-sum", "sliding-window"], + }, + "931": { topicTags: ["array", "dynamic-programming", "matrix"] }, + "932": { topicTags: ["array", "math", "divide-and-conquer"] }, + "933": { topicTags: ["design", "queue", "data-stream"] }, + "934": { + topicTags: ["depth-first-search", "breadth-first-search", "array", "matrix"], + }, + "935": { topicTags: ["dynamic-programming"] }, + "936": { topicTags: ["stack", "greedy", "queue", "string"] }, + "937": { topicTags: ["array", "string", "sorting"] }, + "938": { + topicTags: ["tree", "depth-first-search", "binary-search-tree", "binary-tree"], + }, + "939": { + topicTags: ["geometry", "array", "hash-table", "math", "sorting"], + }, + "940": { topicTags: ["string", "dynamic-programming"] }, + "941": { topicTags: ["array"] }, + "942": { topicTags: ["greedy", "array", "two-pointers", "string"] }, + "943": { + topicTags: ["bit-manipulation", "array", "string", "dynamic-programming", "bitmask"], + }, + "944": { topicTags: ["array", "string"] }, + "945": { topicTags: ["greedy", "array", "counting", "sorting"] }, + "946": { topicTags: ["stack", "array", "simulation"] }, + "947": { topicTags: ["depth-first-search", "union-find", "graph"] }, + "948": { topicTags: ["greedy", "array", "two-pointers", "sorting"] }, + "949": { topicTags: ["string", "enumeration"] }, + "950": { topicTags: ["queue", "array", "sorting", "simulation"] }, + "951": { topicTags: ["tree", "depth-first-search", "binary-tree"] }, + "952": { topicTags: ["union-find", "array", "math"] }, + "953": { topicTags: ["array", "hash-table", "string"] }, + "954": { topicTags: ["greedy", "array", "hash-table", "sorting"] }, + "955": { topicTags: ["greedy", "array", "string"] }, + "956": { topicTags: ["array", "dynamic-programming"] }, + "957": { topicTags: ["bit-manipulation", "array", "hash-table", "math"] }, + "958": { topicTags: ["tree", "breadth-first-search", "binary-tree"] }, + "959": { + topicTags: ["depth-first-search", "breadth-first-search", "union-find", "graph"], + }, + "960": { topicTags: ["array", "string", "dynamic-programming"] }, + "961": { topicTags: ["array", "hash-table"] }, + "962": { topicTags: ["stack", "array", "monotonic-stack"] }, + "963": { topicTags: ["geometry", "array", "math"] }, + "964": { topicTags: ["math", "dynamic-programming"] }, + "965": { + topicTags: ["tree", "depth-first-search", "breadth-first-search", "binary-tree"], + }, + "966": { topicTags: ["array", "hash-table", "string"] }, + "967": { topicTags: ["breadth-first-search", "backtracking"] }, + "968": { + topicTags: ["tree", "depth-first-search", "dynamic-programming", "binary-tree"], + }, + "969": { topicTags: ["greedy", "array", "two-pointers", "sorting"] }, + "970": { topicTags: ["hash-table", "math"] }, + "971": { topicTags: ["tree", "depth-first-search", "binary-tree"] }, + "972": { topicTags: ["math", "string"] }, + "973": { + topicTags: ["geometry", "array", "math", "divide-and-conquer", "quickselect", "sorting", "heap-priority-queue"], + }, + "974": { topicTags: ["array", "hash-table", "prefix-sum"] }, + "975": { + topicTags: ["stack", "array", "dynamic-programming", "ordered-set", "monotonic-stack"], + }, + "976": { topicTags: ["greedy", "array", "math", "sorting"] }, + "977": { topicTags: ["array", "two-pointers", "sorting"] }, + "978": { topicTags: ["array", "dynamic-programming", "sliding-window"] }, + "979": { topicTags: ["tree", "depth-first-search", "binary-tree"] }, + "980": { + topicTags: ["bit-manipulation", "array", "backtracking", "matrix"], + }, + "981": { topicTags: ["design", "hash-table", "string", "binary-search"] }, + "982": { topicTags: ["bit-manipulation", "array", "hash-table"] }, + "983": { topicTags: ["array", "dynamic-programming"] }, + "984": { topicTags: ["greedy", "string"] }, + "985": { topicTags: ["array", "simulation"] }, + "986": { topicTags: ["array", "two-pointers"] }, + "987": { + topicTags: ["tree", "depth-first-search", "breadth-first-search", "hash-table", "binary-tree"], + }, + "988": { + topicTags: ["tree", "depth-first-search", "string", "binary-tree"], + }, + "989": { topicTags: ["array", "math"] }, + "990": { topicTags: ["union-find", "graph", "array", "string"] }, + "991": { topicTags: ["greedy", "math"] }, + "992": { topicTags: ["array", "hash-table", "counting", "sliding-window"] }, + "993": { + topicTags: ["tree", "depth-first-search", "breadth-first-search", "binary-tree"], + }, + "994": { topicTags: ["breadth-first-search", "array", "matrix"] }, + "995": { + topicTags: ["bit-manipulation", "queue", "array", "prefix-sum", "sliding-window"], + }, + "996": { + topicTags: ["bit-manipulation", "array", "math", "dynamic-programming", "backtracking", "bitmask"], + }, + "997": { topicTags: ["graph", "array", "hash-table"] }, + "998": { topicTags: ["tree", "binary-tree"] }, + "999": { topicTags: ["array", "matrix", "simulation"] }, + "1000": { topicTags: ["array", "dynamic-programming"] }, + "1001": { topicTags: ["array", "hash-table"] }, + "1002": { topicTags: ["array", "hash-table", "string"] }, + "1003": { topicTags: ["stack", "string"] }, + "1004": { + topicTags: ["array", "binary-search", "prefix-sum", "sliding-window"], + }, + "1005": { topicTags: ["greedy", "array", "sorting"] }, + "1006": { topicTags: ["stack", "math", "simulation"] }, + "1007": { topicTags: ["greedy", "array"] }, + "1008": { + topicTags: ["stack", "tree", "binary-search-tree", "array", "binary-tree", "monotonic-stack"], + }, + "1009": { topicTags: ["bit-manipulation"] }, + "1010": { topicTags: ["array", "hash-table", "counting"] }, + "1011": { topicTags: ["array", "binary-search"] }, + "1012": { topicTags: ["math", "dynamic-programming"] }, + "1013": { topicTags: ["greedy", "array"] }, + "1014": { topicTags: ["array", "dynamic-programming"] }, + "1015": { topicTags: ["hash-table", "math"] }, + "1016": { topicTags: ["string"] }, + "1017": { topicTags: ["math"] }, + "1018": { topicTags: ["array"] }, + "1019": { topicTags: ["stack", "array", "linked-list", "monotonic-stack"] }, + "1020": { + topicTags: ["depth-first-search", "breadth-first-search", "union-find", "array", "matrix"], + }, + "1021": { topicTags: ["stack", "string"] }, + "1022": { topicTags: ["tree", "depth-first-search", "binary-tree"] }, + "1023": { + topicTags: ["trie", "two-pointers", "string", "string-matching"], + }, + "1024": { topicTags: ["greedy", "array", "dynamic-programming"] }, + "1025": { + topicTags: ["brainteaser", "math", "dynamic-programming", "game-theory"], + }, + "1026": { topicTags: ["tree", "depth-first-search", "binary-tree"] }, + "1027": { + topicTags: ["array", "hash-table", "binary-search", "dynamic-programming"], + }, + "1028": { + topicTags: ["tree", "depth-first-search", "string", "binary-tree"], + }, + "1029": { topicTags: ["greedy", "array", "sorting"] }, + "1030": { topicTags: ["geometry", "array", "math", "matrix", "sorting"] }, + "1031": { topicTags: ["array", "dynamic-programming", "sliding-window"] }, + "1032": { topicTags: ["design", "trie", "array", "string", "data-stream"] }, + "1033": { topicTags: ["brainteaser", "math"] }, + "1034": { + topicTags: ["depth-first-search", "breadth-first-search", "array", "matrix"], + }, + "1035": { topicTags: ["array", "dynamic-programming"] }, + "1036": { + topicTags: ["depth-first-search", "breadth-first-search", "array", "hash-table"], + }, + "1037": { topicTags: ["geometry", "array", "math"] }, + "1038": { + topicTags: ["tree", "depth-first-search", "binary-search-tree", "binary-tree"], + }, + "1039": { topicTags: ["array", "dynamic-programming"] }, + "1040": { topicTags: ["array", "math", "two-pointers", "sorting"] }, + "1041": { topicTags: ["math", "string", "simulation"] }, + "1042": { + topicTags: ["depth-first-search", "breadth-first-search", "graph"], + }, + "1043": { topicTags: ["array", "dynamic-programming"] }, + "1044": { + topicTags: ["string", "binary-search", "suffix-array", "sliding-window", "hash-function", "rolling-hash"], + }, + "1045": { topicTags: ["database"] }, + "1046": { topicTags: ["array", "heap-priority-queue"] }, + "1047": { topicTags: ["stack", "string"] }, + "1048": { + topicTags: ["array", "hash-table", "two-pointers", "string", "dynamic-programming"], + }, + "1049": { topicTags: ["array", "dynamic-programming"] }, + "1050": { topicTags: ["database"] }, + "1051": { topicTags: ["array", "counting-sort", "sorting"] }, + "1052": { topicTags: ["array", "sliding-window"] }, + "1053": { topicTags: ["greedy", "array"] }, + "1054": { + topicTags: ["greedy", "array", "hash-table", "counting", "sorting", "heap-priority-queue"], + }, + "1055": { topicTags: ["greedy", "string", "dynamic-programming"] }, + "1056": { topicTags: ["math"] }, + "1057": { topicTags: ["greedy", "array", "sorting"] }, + "1058": { topicTags: ["greedy", "array", "math", "string"] }, + "1059": { topicTags: ["depth-first-search", "graph"] }, + "1060": { topicTags: ["array", "binary-search"] }, + "1061": { topicTags: ["union-find", "string"] }, + "1062": { + topicTags: ["string", "binary-search", "dynamic-programming", "suffix-array", "hash-function", "rolling-hash"], + }, + "1063": { topicTags: ["stack", "array", "monotonic-stack"] }, + "1064": { topicTags: ["array", "binary-search"] }, + "1065": { topicTags: ["trie", "array", "string", "sorting"] }, + "1066": { + topicTags: ["bit-manipulation", "array", "dynamic-programming", "backtracking", "bitmask"], + }, + "1067": { topicTags: ["math", "dynamic-programming"] }, + "1068": { topicTags: ["database"] }, + "1069": { topicTags: ["database"] }, + "1070": { topicTags: ["database"] }, + "1071": { topicTags: ["math", "string"] }, + "1072": { topicTags: ["array", "hash-table", "matrix"] }, + "1073": { topicTags: ["array", "math"] }, + "1074": { topicTags: ["array", "hash-table", "matrix", "prefix-sum"] }, + "1075": { topicTags: ["database"] }, + "1076": { topicTags: ["database"] }, + "1077": { topicTags: ["database"] }, + "1078": { topicTags: ["string"] }, + "1079": { topicTags: ["string", "backtracking"] }, + "1080": { topicTags: ["tree", "depth-first-search", "binary-tree"] }, + "1081": { topicTags: ["stack", "greedy", "string", "monotonic-stack"] }, + "1082": { topicTags: ["database"] }, + "1083": { topicTags: ["database"] }, + "1084": { topicTags: ["database"] }, + "1085": { topicTags: ["array", "math"] }, + "1086": { topicTags: ["array", "hash-table", "sorting"] }, + "1087": { topicTags: ["breadth-first-search", "string", "backtracking"] }, + "1088": { topicTags: ["math", "backtracking"] }, + "1089": { topicTags: ["array", "two-pointers"] }, + "1090": { + topicTags: ["greedy", "array", "hash-table", "counting", "sorting"], + }, + "1091": { topicTags: ["breadth-first-search", "array", "matrix"] }, + "1092": { topicTags: ["string", "dynamic-programming"] }, + "1093": { + topicTags: ["math", "two-pointers", "probability-and-statistics"], + }, + "1094": { + topicTags: ["array", "prefix-sum", "sorting", "simulation", "heap-priority-queue"], + }, + "1095": { topicTags: ["array", "binary-search", "interactive"] }, + "1096": { + topicTags: ["stack", "breadth-first-search", "string", "backtracking"], + }, + "1097": { topicTags: ["database"] }, + "1098": { topicTags: ["database"] }, + "1099": { + topicTags: ["array", "two-pointers", "binary-search", "sorting"], + }, + "1100": { topicTags: ["hash-table", "string", "sliding-window"] }, + "1101": { topicTags: ["union-find", "array"] }, + "1102": { + topicTags: ["depth-first-search", "breadth-first-search", "union-find", "array", "matrix", "heap-priority-queue"], + }, + "1103": { topicTags: ["math", "simulation"] }, + "1104": { topicTags: ["tree", "math", "binary-tree"] }, + "1105": { topicTags: ["array", "dynamic-programming"] }, + "1106": { topicTags: ["stack", "recursion", "string"] }, + "1107": { topicTags: ["database"] }, + "1108": { topicTags: ["string"] }, + "1109": { topicTags: ["array", "prefix-sum"] }, + "1110": { topicTags: ["tree", "depth-first-search", "binary-tree"] }, + "1111": { topicTags: ["stack", "string"] }, + "1112": { topicTags: ["database"] }, + "1113": { topicTags: ["database"] }, + "1114": { topicTags: ["concurrency"] }, + "1115": { topicTags: ["concurrency"] }, + "1116": { topicTags: ["concurrency"] }, + "1117": { topicTags: ["concurrency"] }, + "1118": { topicTags: ["math"] }, + "1119": { topicTags: ["string"] }, + "1120": { topicTags: ["tree", "depth-first-search", "binary-tree"] }, + "1121": { topicTags: ["greedy", "array"] }, + "1122": { topicTags: ["array", "hash-table", "counting-sort", "sorting"] }, + "1123": { + topicTags: ["tree", "depth-first-search", "breadth-first-search", "hash-table", "binary-tree"], + }, + "1124": { + topicTags: ["stack", "array", "hash-table", "prefix-sum", "monotonic-stack"], + }, + "1125": { + topicTags: ["bit-manipulation", "array", "dynamic-programming", "bitmask"], + }, + "1126": { topicTags: ["database"] }, + "1127": { topicTags: ["database"] }, + "1128": { topicTags: ["array", "hash-table", "counting"] }, + "1129": { topicTags: ["breadth-first-search", "graph"] }, + "1130": { + topicTags: ["stack", "greedy", "dynamic-programming", "monotonic-stack"], + }, + "1131": { topicTags: ["array", "math"] }, + "1132": { topicTags: ["database"] }, + "1133": { topicTags: ["array", "hash-table", "sorting"] }, + "1134": { topicTags: ["math"] }, + "1135": { + topicTags: ["union-find", "graph", "minimum-spanning-tree", "heap-priority-queue"], + }, + "1136": { topicTags: ["graph", "topological-sort"] }, + "1137": { topicTags: ["memoization", "math", "dynamic-programming"] }, + "1138": { topicTags: ["hash-table", "string"] }, + "1139": { topicTags: ["array", "dynamic-programming", "matrix"] }, + "1140": { + topicTags: ["array", "math", "dynamic-programming", "game-theory"], + }, + "1141": { topicTags: ["database"] }, + "1142": { topicTags: ["database"] }, + "1143": { topicTags: ["string", "dynamic-programming"] }, + "1144": { topicTags: ["greedy", "array"] }, + "1145": { topicTags: ["tree", "depth-first-search", "binary-tree"] }, + "1146": { topicTags: ["design", "array", "hash-table", "binary-search"] }, + "1147": { + topicTags: ["greedy", "two-pointers", "string", "dynamic-programming", "hash-function", "rolling-hash"], + }, + "1148": { topicTags: ["database"] }, + "1149": { topicTags: ["database"] }, + "1150": { topicTags: ["array", "binary-search"] }, + "1151": { topicTags: ["array", "sliding-window"] }, + "1152": { topicTags: ["array", "hash-table", "sorting"] }, + "1153": { topicTags: ["hash-table", "string"] }, + "1154": { topicTags: ["math", "string"] }, + "1155": { topicTags: ["dynamic-programming"] }, + "1156": { topicTags: ["string", "sliding-window"] }, + "1157": { + topicTags: ["design", "binary-indexed-tree", "segment-tree", "array", "binary-search"], + }, + "1158": { topicTags: ["database"] }, + "1159": { topicTags: ["database"] }, + "1160": { topicTags: ["array", "hash-table", "string"] }, + "1161": { + topicTags: ["tree", "depth-first-search", "breadth-first-search", "binary-tree"], + }, + "1162": { + topicTags: ["breadth-first-search", "array", "dynamic-programming", "matrix"], + }, + "1163": { topicTags: ["two-pointers", "string"] }, + "1164": { topicTags: ["database"] }, + "1165": { topicTags: ["hash-table", "string"] }, + "1166": { topicTags: ["design", "trie", "hash-table", "string"] }, + "1167": { topicTags: ["greedy", "array", "heap-priority-queue"] }, + "1168": { topicTags: ["union-find", "graph", "minimum-spanning-tree"] }, + "1169": { topicTags: ["array", "hash-table", "string", "sorting"] }, + "1170": { + topicTags: ["array", "hash-table", "string", "binary-search", "sorting"], + }, + "1171": { topicTags: ["hash-table", "linked-list"] }, + "1172": { + topicTags: ["stack", "design", "hash-table", "heap-priority-queue"], + }, + "1173": { topicTags: ["database"] }, + "1174": { topicTags: ["database"] }, + "1175": { topicTags: ["math"] }, + "1176": { topicTags: ["array", "sliding-window"] }, + "1177": { + topicTags: ["bit-manipulation", "hash-table", "string", "prefix-sum"], + }, + "1178": { + topicTags: ["bit-manipulation", "trie", "array", "hash-table", "string"], + }, + "1179": { topicTags: ["database"] }, + "1180": { topicTags: ["math", "string"] }, + "1181": { topicTags: ["array", "hash-table", "string", "sorting"] }, + "1182": { topicTags: ["array", "binary-search", "dynamic-programming"] }, + "1183": { topicTags: ["greedy", "heap-priority-queue"] }, + "1184": { topicTags: ["array"] }, + "1185": { topicTags: ["math"] }, + "1186": { topicTags: ["array", "dynamic-programming"] }, + "1187": { topicTags: ["array", "binary-search", "dynamic-programming"] }, + "1188": { topicTags: ["concurrency"] }, + "1189": { topicTags: ["hash-table", "string", "counting"] }, + "1190": { topicTags: ["stack", "string"] }, + "1191": { topicTags: ["array", "dynamic-programming"] }, + "1192": { + topicTags: ["depth-first-search", "graph", "biconnected-component"], + }, + "1193": { topicTags: ["database"] }, + "1194": { topicTags: ["database"] }, + "1195": { topicTags: ["concurrency"] }, + "1196": { topicTags: ["greedy", "array", "sorting"] }, + "1197": { topicTags: ["breadth-first-search"] }, + "1198": { + topicTags: ["array", "hash-table", "binary-search", "counting", "matrix"], + }, + "1199": { topicTags: ["greedy", "math", "heap-priority-queue"] }, + "1200": { topicTags: ["array", "sorting"] }, + "1201": { topicTags: ["math", "binary-search", "number-theory"] }, + "1202": { + topicTags: ["depth-first-search", "breadth-first-search", "union-find", "hash-table", "string"], + }, + "1203": { + topicTags: ["depth-first-search", "breadth-first-search", "graph", "topological-sort"], + }, + "1204": { topicTags: ["database"] }, + "1205": { topicTags: ["database"] }, + "1206": { topicTags: ["design", "linked-list"] }, + "1207": { topicTags: ["array", "hash-table"] }, + "1208": { + topicTags: ["string", "binary-search", "prefix-sum", "sliding-window"], + }, + "1209": { topicTags: ["stack", "string"] }, + "1210": { topicTags: ["breadth-first-search", "array", "matrix"] }, + "1211": { topicTags: ["database"] }, + "1212": { topicTags: ["database"] }, + "1213": { topicTags: ["array", "hash-table", "binary-search", "counting"] }, + "1214": { + topicTags: [ + "stack", + "tree", + "depth-first-search", + "binary-search-tree", + "two-pointers", + "binary-search", + "binary-tree", + ], + }, + "1215": { topicTags: ["breadth-first-search", "backtracking"] }, + "1216": { topicTags: ["string", "dynamic-programming"] }, + "1217": { topicTags: ["greedy", "array", "math"] }, + "1218": { topicTags: ["array", "hash-table", "dynamic-programming"] }, + "1219": { topicTags: ["array", "backtracking", "matrix"] }, + "1220": { topicTags: ["dynamic-programming"] }, + "1221": { topicTags: ["greedy", "string", "counting"] }, + "1222": { topicTags: ["array", "matrix", "simulation"] }, + "1223": { topicTags: ["array", "dynamic-programming"] }, + "1224": { topicTags: ["array", "hash-table"] }, + "1225": { topicTags: ["database"] }, + "1226": { topicTags: ["concurrency"] }, + "1227": { + topicTags: ["brainteaser", "math", "dynamic-programming", "probability-and-statistics"], + }, + "1228": { topicTags: ["array", "math"] }, + "1229": { topicTags: ["array", "two-pointers", "sorting"] }, + "1230": { + topicTags: ["math", "dynamic-programming", "probability-and-statistics"], + }, + "1231": { topicTags: ["array", "binary-search"] }, + "1232": { topicTags: ["geometry", "array", "math"] }, + "1233": { topicTags: ["trie", "array", "string"] }, + "1234": { topicTags: ["string", "sliding-window"] }, + "1235": { + topicTags: ["array", "binary-search", "dynamic-programming", "sorting"], + }, + "1236": { + topicTags: ["depth-first-search", "breadth-first-search", "string", "interactive"], + }, + "1237": { + topicTags: ["math", "two-pointers", "binary-search", "interactive"], + }, + "1238": { topicTags: ["bit-manipulation", "math", "backtracking"] }, + "1239": { + topicTags: ["bit-manipulation", "array", "string", "backtracking"], + }, + "1240": { topicTags: ["dynamic-programming", "backtracking"] }, + "1241": { topicTags: ["database"] }, + "1242": { + topicTags: ["depth-first-search", "breadth-first-search", "concurrency"], + }, + "1243": { topicTags: ["array", "simulation"] }, + "1244": { topicTags: ["design", "hash-table", "sorting"] }, + "1245": { + topicTags: ["tree", "depth-first-search", "breadth-first-search", "graph", "topological-sort"], + }, + "1246": { topicTags: ["array", "dynamic-programming"] }, + "1247": { topicTags: ["greedy", "math", "string"] }, + "1248": { topicTags: ["array", "hash-table", "math", "sliding-window"] }, + "1249": { topicTags: ["stack", "string"] }, + "1250": { topicTags: ["array", "math", "number-theory"] }, + "1251": { topicTags: ["database"] }, + "1252": { topicTags: ["array", "math", "simulation"] }, + "1253": { topicTags: ["greedy", "array", "matrix"] }, + "1254": { + topicTags: ["depth-first-search", "breadth-first-search", "union-find", "array", "matrix"], + }, + "1255": { + topicTags: ["bit-manipulation", "array", "string", "dynamic-programming", "backtracking", "bitmask"], + }, + "1256": { topicTags: ["bit-manipulation", "math", "string"] }, + "1257": { + topicTags: ["tree", "depth-first-search", "breadth-first-search", "array", "hash-table", "string"], + }, + "1258": { + topicTags: ["union-find", "array", "hash-table", "string", "backtracking"], + }, + "1259": { topicTags: ["math", "dynamic-programming"] }, + "1260": { topicTags: ["array", "matrix", "simulation"] }, + "1261": { + topicTags: ["tree", "depth-first-search", "breadth-first-search", "design", "hash-table", "binary-tree"], + }, + "1262": { topicTags: ["greedy", "array", "dynamic-programming"] }, + "1263": { + topicTags: ["breadth-first-search", "array", "matrix", "heap-priority-queue"], + }, + "1264": { topicTags: ["database"] }, + "1265": { + topicTags: ["stack", "recursion", "linked-list", "two-pointers"], + }, + "1266": { topicTags: ["geometry", "array", "math"] }, + "1267": { + topicTags: ["depth-first-search", "breadth-first-search", "union-find", "array", "counting", "matrix"], + }, + "1268": { topicTags: ["trie", "array", "string"] }, + "1269": { topicTags: ["dynamic-programming"] }, + "1270": { topicTags: ["database"] }, + "1271": { topicTags: ["math", "string"] }, + "1272": { topicTags: ["array"] }, + "1273": { + topicTags: ["tree", "depth-first-search", "breadth-first-search"], + }, + "1274": { topicTags: ["array", "divide-and-conquer", "interactive"] }, + "1275": { topicTags: ["array", "hash-table", "matrix", "simulation"] }, + "1276": { topicTags: ["math"] }, + "1277": { topicTags: ["array", "dynamic-programming", "matrix"] }, + "1278": { topicTags: ["string", "dynamic-programming"] }, + "1279": { topicTags: ["concurrency"] }, + "1280": { topicTags: ["database"] }, + "1281": { topicTags: ["math"] }, + "1282": { topicTags: ["array", "hash-table"] }, + "1283": { topicTags: ["array", "binary-search"] }, + "1284": { + topicTags: ["bit-manipulation", "breadth-first-search", "array", "matrix"], + }, + "1285": { topicTags: ["database"] }, + "1286": { topicTags: ["design", "string", "backtracking", "iterator"] }, + "1287": { topicTags: ["array"] }, + "1288": { topicTags: ["array", "sorting"] }, + "1289": { topicTags: ["array", "dynamic-programming", "matrix"] }, + "1290": { topicTags: ["linked-list", "math"] }, + "1291": { topicTags: ["enumeration"] }, + "1292": { topicTags: ["array", "binary-search", "matrix", "prefix-sum"] }, + "1293": { topicTags: ["breadth-first-search", "array", "matrix"] }, + "1294": { topicTags: ["database"] }, + "1295": { topicTags: ["array"] }, + "1296": { topicTags: ["greedy", "array", "hash-table", "sorting"] }, + "1297": { topicTags: ["hash-table", "string", "sliding-window"] }, + "1298": { topicTags: ["breadth-first-search", "array"] }, + "1299": { topicTags: ["array"] }, + "1300": { topicTags: ["array", "binary-search", "sorting"] }, + "1301": { topicTags: ["array", "dynamic-programming", "matrix"] }, + "1302": { + topicTags: ["tree", "depth-first-search", "breadth-first-search", "binary-tree"], + }, + "1303": { topicTags: ["database"] }, + "1304": { topicTags: ["array", "math"] }, + "1305": { + topicTags: ["tree", "depth-first-search", "binary-search-tree", "binary-tree", "sorting"], + }, + "1306": { + topicTags: ["depth-first-search", "breadth-first-search", "array"], + }, + "1307": { topicTags: ["array", "math", "string", "backtracking"] }, + "1308": { topicTags: ["database"] }, + "1309": { topicTags: ["string"] }, + "1310": { topicTags: ["bit-manipulation", "array", "prefix-sum"] }, + "1311": { + topicTags: ["breadth-first-search", "array", "hash-table", "sorting"], + }, + "1312": { topicTags: ["string", "dynamic-programming"] }, + "1313": { topicTags: ["array"] }, + "1314": { topicTags: ["array", "matrix", "prefix-sum"] }, + "1315": { + topicTags: ["tree", "depth-first-search", "breadth-first-search", "binary-tree"], + }, + "1316": { topicTags: ["trie", "string", "hash-function", "rolling-hash"] }, + "1317": { topicTags: ["math"] }, + "1318": { topicTags: ["bit-manipulation"] }, + "1319": { + topicTags: ["depth-first-search", "breadth-first-search", "union-find", "graph"], + }, + "1320": { topicTags: ["string", "dynamic-programming"] }, + "1321": { topicTags: ["database"] }, + "1322": { topicTags: ["database"] }, + "1323": { topicTags: ["greedy", "math"] }, + "1324": { topicTags: ["array", "string", "simulation"] }, + "1325": { topicTags: ["tree", "depth-first-search", "binary-tree"] }, + "1326": { topicTags: ["greedy", "array", "dynamic-programming"] }, + "1327": { topicTags: ["database"] }, + "1328": { topicTags: ["greedy", "string"] }, + "1329": { topicTags: ["array", "matrix", "sorting"] }, + "1330": { topicTags: ["greedy", "array", "math"] }, + "1331": { topicTags: ["array", "hash-table", "sorting"] }, + "1332": { topicTags: ["two-pointers", "string"] }, + "1333": { topicTags: ["array", "sorting"] }, + "1334": { topicTags: ["graph", "dynamic-programming", "shortest-path"] }, + "1335": { topicTags: ["array", "dynamic-programming"] }, + "1336": { topicTags: ["database"] }, + "1337": { + topicTags: ["array", "binary-search", "matrix", "sorting", "heap-priority-queue"], + }, + "1338": { + topicTags: ["greedy", "array", "hash-table", "sorting", "heap-priority-queue"], + }, + "1339": { topicTags: ["tree", "depth-first-search", "binary-tree"] }, + "1340": { topicTags: ["array", "dynamic-programming", "sorting"] }, + "1341": { topicTags: ["database"] }, + "1342": { topicTags: ["bit-manipulation", "math"] }, + "1343": { topicTags: ["array", "sliding-window"] }, + "1344": { topicTags: ["math"] }, + "1345": { topicTags: ["breadth-first-search", "array", "hash-table"] }, + "1346": { + topicTags: ["array", "hash-table", "two-pointers", "binary-search", "sorting"], + }, + "1347": { topicTags: ["hash-table", "string", "counting"] }, + "1348": { + topicTags: ["design", "hash-table", "binary-search", "ordered-set", "sorting"], + }, + "1349": { + topicTags: ["bit-manipulation", "array", "dynamic-programming", "bitmask", "matrix"], + }, + "1350": { topicTags: ["database"] }, + "1351": { topicTags: ["array", "binary-search", "matrix"] }, + "1352": { topicTags: ["design", "queue", "array", "math", "data-stream"] }, + "1353": { topicTags: ["greedy", "array", "heap-priority-queue"] }, + "1354": { topicTags: ["array", "heap-priority-queue"] }, + "1355": { topicTags: ["database"] }, + "1356": { topicTags: ["bit-manipulation", "array", "counting", "sorting"] }, + "1357": { topicTags: ["design", "array", "hash-table"] }, + "1358": { topicTags: ["hash-table", "string", "sliding-window"] }, + "1359": { topicTags: ["math", "dynamic-programming", "combinatorics"] }, + "1360": { topicTags: ["math", "string"] }, + "1361": { + topicTags: ["tree", "depth-first-search", "breadth-first-search", "union-find", "graph", "binary-tree"], + }, + "1362": { topicTags: ["math"] }, + "1363": { topicTags: ["greedy", "array", "dynamic-programming"] }, + "1364": { topicTags: ["database"] }, + "1365": { topicTags: ["array", "hash-table", "counting", "sorting"] }, + "1366": { + topicTags: ["array", "hash-table", "string", "counting", "sorting"], + }, + "1367": { + topicTags: ["tree", "depth-first-search", "breadth-first-search", "linked-list", "binary-tree"], + }, + "1368": { + topicTags: ["breadth-first-search", "graph", "array", "matrix", "shortest-path", "heap-priority-queue"], + }, + "1369": { topicTags: ["database"] }, + "1370": { topicTags: ["hash-table", "string", "counting"] }, + "1371": { + topicTags: ["bit-manipulation", "hash-table", "string", "prefix-sum"], + }, + "1372": { + topicTags: ["tree", "depth-first-search", "dynamic-programming", "binary-tree"], + }, + "1373": { + topicTags: ["tree", "depth-first-search", "binary-search-tree", "dynamic-programming", "binary-tree"], + }, + "1374": { topicTags: ["string"] }, + "1375": { topicTags: ["array"] }, + "1376": { + topicTags: ["tree", "depth-first-search", "breadth-first-search"], + }, + "1377": { + topicTags: ["tree", "depth-first-search", "breadth-first-search", "graph"], + }, + "1378": { topicTags: ["database"] }, + "1379": { + topicTags: ["tree", "depth-first-search", "breadth-first-search", "binary-tree"], + }, + "1380": { topicTags: ["array", "matrix"] }, + "1381": { topicTags: ["stack", "design", "array"] }, + "1382": { + topicTags: ["greedy", "tree", "depth-first-search", "binary-search-tree", "divide-and-conquer", "binary-tree"], + }, + "1383": { + topicTags: ["greedy", "array", "sorting", "heap-priority-queue"], + }, + "1384": { topicTags: ["database"] }, + "1385": { + topicTags: ["array", "two-pointers", "binary-search", "sorting"], + }, + "1386": { + topicTags: ["greedy", "bit-manipulation", "array", "hash-table"], + }, + "1387": { topicTags: ["memoization", "dynamic-programming", "sorting"] }, + "1388": { + topicTags: ["greedy", "array", "dynamic-programming", "heap-priority-queue"], + }, + "1389": { topicTags: ["array", "simulation"] }, + "1390": { topicTags: ["array", "math"] }, + "1391": { + topicTags: ["depth-first-search", "breadth-first-search", "union-find", "array", "matrix"], + }, + "1392": { + topicTags: ["string", "string-matching", "hash-function", "rolling-hash"], + }, + "1393": { topicTags: ["database"] }, + "1394": { topicTags: ["array", "hash-table", "counting"] }, + "1395": { + topicTags: ["binary-indexed-tree", "array", "dynamic-programming"], + }, + "1396": { topicTags: ["design", "hash-table", "string"] }, + "1397": { topicTags: ["string", "dynamic-programming", "string-matching"] }, + "1398": { topicTags: ["database"] }, + "1399": { topicTags: ["hash-table", "math"] }, + "1400": { topicTags: ["greedy", "hash-table", "string", "counting"] }, + "1401": { topicTags: ["geometry", "math"] }, + "1402": { + topicTags: ["greedy", "array", "dynamic-programming", "sorting"], + }, + "1403": { topicTags: ["greedy", "array", "sorting"] }, + "1404": { topicTags: ["bit-manipulation", "string"] }, + "1405": { topicTags: ["greedy", "string", "heap-priority-queue"] }, + "1406": { + topicTags: ["array", "math", "dynamic-programming", "game-theory"], + }, + "1407": { topicTags: ["database"] }, + "1408": { topicTags: ["string", "string-matching"] }, + "1409": { topicTags: ["binary-indexed-tree", "array", "simulation"] }, + "1410": { topicTags: ["hash-table", "string"] }, + "1411": { topicTags: ["dynamic-programming"] }, + "1412": { topicTags: ["database"] }, + "1413": { topicTags: ["array", "prefix-sum"] }, + "1414": { topicTags: ["greedy"] }, + "1415": { topicTags: ["string", "backtracking"] }, + "1416": { topicTags: ["string", "dynamic-programming"] }, + "1417": { topicTags: ["string"] }, + "1418": { + topicTags: ["array", "hash-table", "string", "ordered-set", "sorting"], + }, + "1419": { topicTags: ["string", "counting"] }, + "1420": { topicTags: ["dynamic-programming"] }, + "1421": { topicTags: ["database"] }, + "1422": { topicTags: ["string"] }, + "1423": { topicTags: ["array", "prefix-sum", "sliding-window"] }, + "1424": { topicTags: ["array", "sorting", "heap-priority-queue"] }, + "1425": { + topicTags: ["queue", "array", "dynamic-programming", "sliding-window", "monotonic-queue", "heap-priority-queue"], + }, + "1426": { topicTags: ["array", "hash-table"] }, + "1427": { topicTags: ["array", "math", "string"] }, + "1428": { topicTags: ["array", "binary-search", "interactive", "matrix"] }, + "1429": { + topicTags: ["design", "queue", "array", "hash-table", "data-stream"], + }, + "1430": { + topicTags: ["tree", "depth-first-search", "breadth-first-search", "binary-tree"], + }, + "1431": { topicTags: ["array"] }, + "1432": { topicTags: ["greedy", "math"] }, + "1433": { topicTags: ["greedy", "string", "sorting"] }, + "1434": { + topicTags: ["bit-manipulation", "array", "dynamic-programming", "bitmask"], + }, + "1435": { topicTags: ["database"] }, + "1436": { topicTags: ["hash-table", "string"] }, + "1437": { topicTags: ["array"] }, + "1438": { + topicTags: ["queue", "array", "ordered-set", "sliding-window", "monotonic-queue", "heap-priority-queue"], + }, + "1439": { + topicTags: ["array", "binary-search", "matrix", "heap-priority-queue"], + }, + "1440": { topicTags: ["database"] }, + "1441": { topicTags: ["stack", "array", "simulation"] }, + "1442": { + topicTags: ["bit-manipulation", "array", "hash-table", "math", "prefix-sum"], + }, + "1443": { + topicTags: ["tree", "depth-first-search", "breadth-first-search", "hash-table"], + }, + "1444": { + topicTags: ["memoization", "array", "dynamic-programming", "matrix"], + }, + "1445": { topicTags: ["database"] }, + "1446": { topicTags: ["string"] }, + "1447": { topicTags: ["math", "string", "number-theory"] }, + "1448": { + topicTags: ["tree", "depth-first-search", "breadth-first-search", "binary-tree"], + }, + "1449": { topicTags: ["array", "dynamic-programming"] }, + "1450": { topicTags: ["array"] }, + "1451": { topicTags: ["string", "sorting"] }, + "1452": { topicTags: ["array", "hash-table", "string"] }, + "1453": { topicTags: ["geometry", "array", "math"] }, + "1454": { topicTags: ["database"] }, + "1455": { topicTags: ["string", "string-matching"] }, + "1456": { topicTags: ["string", "sliding-window"] }, + "1457": { + topicTags: ["bit-manipulation", "tree", "depth-first-search", "breadth-first-search", "binary-tree"], + }, + "1458": { topicTags: ["array", "dynamic-programming"] }, + "1459": { topicTags: ["database"] }, + "1460": { topicTags: ["array", "hash-table", "sorting"] }, + "1461": { + topicTags: ["bit-manipulation", "hash-table", "string", "hash-function", "rolling-hash"], + }, + "1462": { + topicTags: ["depth-first-search", "breadth-first-search", "graph", "topological-sort"], + }, + "1463": { topicTags: ["array", "dynamic-programming", "matrix"] }, + "1464": { topicTags: ["array", "sorting", "heap-priority-queue"] }, + "1465": { topicTags: ["greedy", "array", "sorting"] }, + "1466": { + topicTags: ["depth-first-search", "breadth-first-search", "graph"], + }, + "1467": { + topicTags: ["math", "dynamic-programming", "backtracking", "combinatorics", "probability-and-statistics"], + }, + "1468": { topicTags: ["database"] }, + "1469": { + topicTags: ["tree", "depth-first-search", "breadth-first-search", "binary-tree"], + }, + "1470": { topicTags: ["array"] }, + "1471": { topicTags: ["array", "two-pointers", "sorting"] }, + "1472": { + topicTags: ["stack", "design", "array", "linked-list", "data-stream", "doubly-linked-list"], + }, + "1473": { topicTags: ["array", "dynamic-programming"] }, + "1474": { topicTags: ["linked-list"] }, + "1475": { topicTags: ["stack", "array", "monotonic-stack"] }, + "1476": { topicTags: ["design", "array", "matrix"] }, + "1477": { + topicTags: ["array", "hash-table", "binary-search", "dynamic-programming", "sliding-window"], + }, + "1478": { topicTags: ["array", "math", "dynamic-programming", "sorting"] }, + "1479": { topicTags: ["database"] }, + "1480": { topicTags: ["array", "prefix-sum"] }, + "1481": { + topicTags: ["greedy", "array", "hash-table", "counting", "sorting"], + }, + "1482": { topicTags: ["array", "binary-search"] }, + "1483": { + topicTags: [ + "tree", + "depth-first-search", + "breadth-first-search", + "design", + "binary-search", + "dynamic-programming", + ], + }, + "1484": { topicTags: ["database"] }, + "1485": { + topicTags: ["tree", "depth-first-search", "breadth-first-search", "hash-table", "binary-tree"], + }, + "1486": { topicTags: ["bit-manipulation", "math"] }, + "1487": { topicTags: ["array", "hash-table", "string"] }, + "1488": { + topicTags: ["greedy", "array", "hash-table", "binary-search", "heap-priority-queue"], + }, + "1489": { + topicTags: ["union-find", "graph", "minimum-spanning-tree", "sorting", "strongly-connected-component"], + }, + "1490": { + topicTags: ["tree", "depth-first-search", "breadth-first-search", "hash-table"], + }, + "1491": { topicTags: ["array", "sorting"] }, + "1492": { topicTags: ["math"] }, + "1493": { topicTags: ["array", "dynamic-programming", "sliding-window"] }, + "1494": { + topicTags: ["bit-manipulation", "graph", "dynamic-programming", "bitmask"], + }, + "1495": { topicTags: ["database"] }, + "1496": { topicTags: ["hash-table", "string"] }, + "1497": { topicTags: ["array", "hash-table", "counting"] }, + "1498": { + topicTags: ["array", "two-pointers", "binary-search", "sorting"], + }, + "1499": { + topicTags: ["queue", "array", "sliding-window", "monotonic-queue", "heap-priority-queue"], + }, + "1500": { + topicTags: ["design", "hash-table", "data-stream", "heap-priority-queue"], + }, + "1501": { topicTags: ["database"] }, + "1502": { topicTags: ["array", "sorting"] }, + "1503": { topicTags: ["brainteaser", "array", "simulation"] }, + "1504": { + topicTags: ["stack", "array", "dynamic-programming", "matrix", "monotonic-stack"], + }, + "1505": { + topicTags: ["greedy", "binary-indexed-tree", "segment-tree", "string"], + }, + "1506": { + topicTags: ["bit-manipulation", "tree", "depth-first-search", "hash-table"], + }, + "1507": { topicTags: ["string"] }, + "1508": { + topicTags: ["array", "two-pointers", "binary-search", "sorting"], + }, + "1509": { topicTags: ["greedy", "array", "sorting"] }, + "1510": { topicTags: ["math", "dynamic-programming", "game-theory"] }, + "1511": { topicTags: ["database"] }, + "1512": { topicTags: ["array", "hash-table", "math", "counting"] }, + "1513": { topicTags: ["math", "string"] }, + "1514": { topicTags: ["graph", "shortest-path", "heap-priority-queue"] }, + "1515": { topicTags: ["geometry", "math", "randomized"] }, + "1516": { topicTags: ["tree", "depth-first-search"] }, + "1517": { topicTags: ["database"] }, + "1518": { topicTags: ["math", "simulation"] }, + "1519": { + topicTags: ["tree", "depth-first-search", "breadth-first-search", "hash-table", "counting"], + }, + "1520": { topicTags: ["greedy", "string"] }, + "1521": { + topicTags: ["bit-manipulation", "segment-tree", "array", "binary-search"], + }, + "1522": { topicTags: ["tree", "depth-first-search"] }, + "1523": { topicTags: ["math"] }, + "1524": { + topicTags: ["array", "math", "dynamic-programming", "prefix-sum"], + }, + "1525": { + topicTags: ["bit-manipulation", "string", "dynamic-programming"], + }, + "1526": { + topicTags: ["stack", "greedy", "array", "dynamic-programming", "monotonic-stack"], + }, + "1527": { topicTags: ["database"] }, + "1528": { topicTags: ["array", "string"] }, + "1529": { topicTags: ["greedy", "string"] }, + "1530": { topicTags: ["tree", "depth-first-search", "binary-tree"] }, + "1531": { topicTags: ["string", "dynamic-programming"] }, + "1532": { topicTags: ["database"] }, + "1533": { topicTags: ["array", "binary-search", "interactive"] }, + "1534": { topicTags: ["array", "enumeration"] }, + "1535": { topicTags: ["array", "simulation"] }, + "1536": { topicTags: ["greedy", "array", "matrix"] }, + "1537": { + topicTags: ["greedy", "array", "two-pointers", "dynamic-programming"], + }, + "1538": { topicTags: ["array", "math", "interactive"] }, + "1539": { topicTags: ["array", "binary-search"] }, + "1540": { topicTags: ["hash-table", "string"] }, + "1541": { topicTags: ["stack", "greedy", "string"] }, + "1542": { topicTags: ["bit-manipulation", "hash-table", "string"] }, + "1543": { topicTags: ["database"] }, + "1544": { topicTags: ["stack", "string"] }, + "1545": { topicTags: ["recursion", "string"] }, + "1546": { topicTags: ["greedy", "array", "hash-table", "prefix-sum"] }, + "1547": { topicTags: ["array", "dynamic-programming"] }, + "1548": { topicTags: ["graph", "dynamic-programming"] }, + "1549": { topicTags: ["database"] }, + "1550": { topicTags: ["array"] }, + "1551": { topicTags: ["math"] }, + "1552": { topicTags: ["array", "binary-search", "sorting"] }, + "1553": { topicTags: ["memoization", "dynamic-programming"] }, + "1554": { + topicTags: ["hash-table", "string", "hash-function", "rolling-hash"], + }, + "1555": { topicTags: ["database"] }, + "1556": { topicTags: ["string"] }, + "1557": { topicTags: ["graph"] }, + "1558": { topicTags: ["greedy", "array"] }, + "1559": { + topicTags: ["depth-first-search", "breadth-first-search", "union-find", "array", "matrix"], + }, + "1560": { topicTags: ["array", "simulation"] }, + "1561": { + topicTags: ["greedy", "array", "math", "game-theory", "sorting"], + }, + "1562": { topicTags: ["array", "binary-search", "simulation"] }, + "1563": { + topicTags: ["array", "math", "dynamic-programming", "game-theory"], + }, + "1564": { topicTags: ["greedy", "array", "sorting"] }, + "1565": { topicTags: ["database"] }, + "1566": { topicTags: ["array", "enumeration"] }, + "1567": { topicTags: ["greedy", "array", "dynamic-programming"] }, + "1568": { + topicTags: ["depth-first-search", "breadth-first-search", "array", "matrix", "strongly-connected-component"], + }, + "1569": { + topicTags: [ + "tree", + "union-find", + "binary-search-tree", + "memoization", + "array", + "math", + "divide-and-conquer", + "dynamic-programming", + "binary-tree", + "combinatorics", + ], + }, + "1570": { topicTags: ["design", "array", "hash-table", "two-pointers"] }, + "1571": { topicTags: ["database"] }, + "1572": { topicTags: ["array", "matrix"] }, + "1573": { topicTags: ["math", "string"] }, + "1574": { + topicTags: ["stack", "array", "two-pointers", "binary-search", "monotonic-stack"], + }, + "1575": { topicTags: ["memoization", "array", "dynamic-programming"] }, + "1576": { topicTags: ["string"] }, + "1577": { topicTags: ["array", "hash-table", "math", "two-pointers"] }, + "1578": { topicTags: ["greedy", "array", "string", "dynamic-programming"] }, + "1579": { topicTags: ["union-find", "graph"] }, + "1580": { topicTags: ["greedy", "array", "sorting"] }, + "1581": { topicTags: ["database"] }, + "1582": { topicTags: ["array", "matrix"] }, + "1583": { topicTags: ["array", "simulation"] }, + "1584": { topicTags: ["union-find", "array", "minimum-spanning-tree"] }, + "1585": { topicTags: ["greedy", "string", "sorting"] }, + "1586": { + topicTags: ["stack", "tree", "design", "binary-search-tree", "binary-tree", "iterator"], + }, + "1587": { topicTags: ["database"] }, + "1588": { topicTags: ["array", "math", "prefix-sum"] }, + "1589": { topicTags: ["greedy", "array", "prefix-sum", "sorting"] }, + "1590": { topicTags: ["array", "hash-table", "prefix-sum"] }, + "1591": { topicTags: ["graph", "topological-sort", "array", "matrix"] }, + "1592": { topicTags: ["string"] }, + "1593": { topicTags: ["hash-table", "string", "backtracking"] }, + "1594": { topicTags: ["array", "dynamic-programming", "matrix"] }, + "1595": { + topicTags: ["bit-manipulation", "array", "dynamic-programming", "bitmask", "matrix"], + }, + "1596": { topicTags: ["database"] }, + "1597": { topicTags: ["stack", "tree", "string", "binary-tree"] }, + "1598": { topicTags: ["stack", "array", "string"] }, + "1599": { topicTags: ["array", "simulation"] }, + "1600": { + topicTags: ["tree", "depth-first-search", "design", "hash-table"], + }, + "1601": { + topicTags: ["bit-manipulation", "array", "backtracking", "enumeration"], + }, + "1602": { topicTags: ["tree", "breadth-first-search", "binary-tree"] }, + "1603": { topicTags: ["design", "counting", "simulation"] }, + "1604": { topicTags: ["array", "hash-table", "string", "sorting"] }, + "1605": { topicTags: ["greedy", "array", "matrix"] }, + "1606": { + topicTags: ["greedy", "array", "ordered-set", "heap-priority-queue"], + }, + "1607": { topicTags: ["database"] }, + "1608": { topicTags: ["array", "binary-search", "sorting"] }, + "1609": { topicTags: ["tree", "breadth-first-search", "binary-tree"] }, + "1610": { + topicTags: ["geometry", "array", "math", "sorting", "sliding-window"], + }, + "1611": { + topicTags: ["bit-manipulation", "memoization", "dynamic-programming"], + }, + "1612": { topicTags: ["tree", "depth-first-search", "binary-tree"] }, + "1613": { topicTags: ["database"] }, + "1614": { topicTags: ["stack", "string"] }, + "1615": { topicTags: ["graph"] }, + "1616": { topicTags: ["two-pointers", "string"] }, + "1617": { + topicTags: ["bit-manipulation", "tree", "dynamic-programming", "bitmask", "enumeration"], + }, + "1618": { topicTags: ["array", "string", "binary-search", "interactive"] }, + "1619": { topicTags: ["array", "sorting"] }, + "1620": { topicTags: ["array", "enumeration"] }, + "1621": { topicTags: ["math", "dynamic-programming"] }, + "1622": { topicTags: ["design", "segment-tree", "math"] }, + "1623": { topicTags: ["database"] }, + "1624": { topicTags: ["hash-table", "string"] }, + "1625": { topicTags: ["breadth-first-search", "string"] }, + "1626": { topicTags: ["array", "dynamic-programming", "sorting"] }, + "1627": { topicTags: ["union-find", "array", "math"] }, + "1628": { topicTags: ["stack", "tree", "design", "math", "binary-tree"] }, + "1629": { topicTags: ["array", "string"] }, + "1630": { topicTags: ["array", "sorting"] }, + "1631": { + topicTags: [ + "depth-first-search", + "breadth-first-search", + "union-find", + "array", + "binary-search", + "matrix", + "heap-priority-queue", + ], + }, + "1632": { + topicTags: ["greedy", "union-find", "graph", "topological-sort", "array", "matrix"], + }, + "1633": { topicTags: ["database"] }, + "1634": { topicTags: ["linked-list", "math", "two-pointers"] }, + "1635": { topicTags: ["database"] }, + "1636": { topicTags: ["array", "hash-table", "sorting"] }, + "1637": { topicTags: ["array", "sorting"] }, + "1638": { topicTags: ["hash-table", "string", "dynamic-programming"] }, + "1639": { topicTags: ["array", "string", "dynamic-programming"] }, + "1640": { topicTags: ["array", "hash-table"] }, + "1641": { topicTags: ["dynamic-programming"] }, + "1642": { topicTags: ["greedy", "array", "heap-priority-queue"] }, + "1643": { + topicTags: ["array", "math", "dynamic-programming", "combinatorics"], + }, + "1644": { topicTags: ["tree", "depth-first-search", "binary-tree"] }, + "1645": { topicTags: ["database"] }, + "1646": { topicTags: ["array", "dynamic-programming", "simulation"] }, + "1647": { topicTags: ["greedy", "string", "sorting"] }, + "1648": { + topicTags: ["greedy", "array", "math", "binary-search", "sorting", "heap-priority-queue"], + }, + "1649": { + topicTags: [ + "binary-indexed-tree", + "segment-tree", + "array", + "binary-search", + "divide-and-conquer", + "ordered-set", + "merge-sort", + ], + }, + "1650": { topicTags: ["tree", "hash-table", "binary-tree"] }, + "1651": { topicTags: ["database"] }, + "1652": { topicTags: ["array"] }, + "1653": { topicTags: ["stack", "string", "dynamic-programming"] }, + "1654": { + topicTags: ["breadth-first-search", "array", "dynamic-programming"], + }, + "1655": { + topicTags: ["bit-manipulation", "array", "dynamic-programming", "backtracking", "bitmask"], + }, + "1656": { topicTags: ["design", "array", "hash-table", "data-stream"] }, + "1657": { topicTags: ["hash-table", "string", "sorting"] }, + "1658": { + topicTags: ["array", "hash-table", "binary-search", "prefix-sum", "sliding-window"], + }, + "1659": { + topicTags: ["bit-manipulation", "memoization", "dynamic-programming", "bitmask"], + }, + "1660": { + topicTags: ["tree", "depth-first-search", "breadth-first-search", "hash-table", "binary-tree"], + }, + "1661": { topicTags: ["database"] }, + "1662": { topicTags: ["array", "string"] }, + "1663": { topicTags: ["greedy", "string"] }, + "1664": { topicTags: ["array", "dynamic-programming"] }, + "1665": { topicTags: ["greedy", "array", "sorting"] }, + "1666": { topicTags: ["tree", "depth-first-search", "binary-tree"] }, + "1667": { topicTags: ["database"] }, + "1668": { topicTags: ["string", "string-matching"] }, + "1669": { topicTags: ["linked-list"] }, + "1670": { + topicTags: ["design", "queue", "array", "linked-list", "data-stream"], + }, + "1671": { + topicTags: ["greedy", "array", "binary-search", "dynamic-programming"], + }, + "1672": { topicTags: ["array", "matrix"] }, + "1673": { topicTags: ["stack", "greedy", "array", "monotonic-stack"] }, + "1674": { topicTags: ["array", "hash-table", "prefix-sum"] }, + "1675": { + topicTags: ["greedy", "array", "ordered-set", "heap-priority-queue"], + }, + "1676": { topicTags: ["tree", "depth-first-search", "binary-tree"] }, + "1677": { topicTags: ["database"] }, + "1678": { topicTags: ["string"] }, + "1679": { topicTags: ["array", "hash-table", "two-pointers", "sorting"] }, + "1680": { topicTags: ["bit-manipulation", "math", "simulation"] }, + "1681": { + topicTags: ["bit-manipulation", "array", "dynamic-programming", "bitmask"], + }, + "1682": { topicTags: ["string", "dynamic-programming"] }, + "1683": { topicTags: ["database"] }, + "1684": { + topicTags: ["bit-manipulation", "array", "hash-table", "string"], + }, + "1685": { topicTags: ["array", "math", "prefix-sum"] }, + "1686": { + topicTags: ["greedy", "array", "math", "game-theory", "sorting", "heap-priority-queue"], + }, + "1687": { + topicTags: ["segment-tree", "queue", "array", "dynamic-programming", "monotonic-queue", "heap-priority-queue"], + }, + "1688": { topicTags: ["math", "simulation"] }, + "1689": { topicTags: ["greedy", "string"] }, + "1690": { + topicTags: ["array", "math", "dynamic-programming", "game-theory"], + }, + "1691": { topicTags: ["array", "dynamic-programming", "sorting"] }, + "1692": { topicTags: ["dynamic-programming"] }, + "1693": { topicTags: ["database"] }, + "1694": { topicTags: ["string"] }, + "1695": { topicTags: ["array", "hash-table", "sliding-window"] }, + "1696": { + topicTags: ["queue", "array", "dynamic-programming", "sliding-window", "monotonic-queue", "heap-priority-queue"], + }, + "1697": { topicTags: ["union-find", "graph", "array", "sorting"] }, + "1698": { + topicTags: ["trie", "string", "suffix-array", "hash-function", "rolling-hash"], + }, + "1699": { topicTags: ["database"] }, + "1700": { topicTags: ["stack", "queue", "array", "simulation"] }, + "1701": { topicTags: ["array", "simulation"] }, + "1702": { topicTags: ["greedy", "string"] }, + "1703": { topicTags: ["greedy", "array", "prefix-sum", "sliding-window"] }, + "1704": { topicTags: ["string", "counting"] }, + "1705": { topicTags: ["greedy", "array", "heap-priority-queue"] }, + "1706": { + topicTags: ["depth-first-search", "array", "dynamic-programming", "matrix", "simulation"], + }, + "1707": { topicTags: ["bit-manipulation", "trie", "array"] }, + "1708": { topicTags: ["greedy", "array"] }, + "1709": { topicTags: ["database"] }, + "1710": { topicTags: ["greedy", "array", "sorting"] }, + "1711": { topicTags: ["array", "hash-table"] }, + "1712": { + topicTags: ["array", "two-pointers", "binary-search", "prefix-sum"], + }, + "1713": { topicTags: ["greedy", "array", "hash-table", "binary-search"] }, + "1714": { topicTags: ["array", "dynamic-programming"] }, + "1715": { topicTags: ["database"] }, + "1716": { topicTags: ["math"] }, + "1717": { topicTags: ["stack", "greedy", "string"] }, + "1718": { topicTags: ["array", "backtracking"] }, + "1719": { topicTags: ["tree", "graph", "topological-sort"] }, + "1720": { topicTags: ["bit-manipulation", "array"] }, + "1721": { topicTags: ["linked-list", "two-pointers"] }, + "1722": { topicTags: ["depth-first-search", "union-find", "array"] }, + "1723": { + topicTags: ["bit-manipulation", "array", "dynamic-programming", "backtracking", "bitmask"], + }, + "1724": { topicTags: ["union-find", "graph", "minimum-spanning-tree"] }, + "1725": { topicTags: ["array"] }, + "1726": { topicTags: ["array", "hash-table"] }, + "1727": { topicTags: ["greedy", "array", "matrix", "sorting"] }, + "1728": { + topicTags: [ + "graph", + "topological-sort", + "memoization", + "array", + "math", + "dynamic-programming", + "game-theory", + "matrix", + ], + }, + "1729": { topicTags: ["database"] }, + "1730": { topicTags: ["breadth-first-search", "array", "matrix"] }, + "1731": { topicTags: ["database"] }, + "1732": { topicTags: ["array", "prefix-sum"] }, + "1733": { topicTags: ["greedy", "array"] }, + "1734": { topicTags: ["bit-manipulation", "array"] }, + "1735": { + topicTags: ["array", "math", "dynamic-programming", "combinatorics", "number-theory"], + }, + "1736": { topicTags: ["string"] }, + "1737": { topicTags: ["hash-table", "string", "counting", "prefix-sum"] }, + "1738": { + topicTags: [ + "bit-manipulation", + "array", + "divide-and-conquer", + "matrix", + "prefix-sum", + "quickselect", + "heap-priority-queue", + ], + }, + "1739": { topicTags: ["greedy", "math", "binary-search"] }, + "1740": { + topicTags: ["tree", "depth-first-search", "breadth-first-search", "hash-table", "binary-tree"], + }, + "1741": { topicTags: ["database"] }, + "1742": { topicTags: ["hash-table", "math", "counting"] }, + "1743": { topicTags: ["array", "hash-table"] }, + "1744": { topicTags: ["array", "prefix-sum"] }, + "1745": { topicTags: ["string", "dynamic-programming"] }, + "1746": { topicTags: ["array", "dynamic-programming"] }, + "1747": { topicTags: ["database"] }, + "1748": { topicTags: ["array", "hash-table", "counting"] }, + "1749": { topicTags: ["array", "dynamic-programming"] }, + "1750": { topicTags: ["two-pointers", "string"] }, + "1751": { topicTags: ["array", "binary-search", "dynamic-programming"] }, + "1752": { topicTags: ["array"] }, + "1753": { topicTags: ["greedy", "math", "heap-priority-queue"] }, + "1754": { topicTags: ["greedy", "two-pointers", "string"] }, + "1755": { + topicTags: ["bit-manipulation", "array", "two-pointers", "dynamic-programming", "bitmask"], + }, + "1756": { + topicTags: ["stack", "design", "binary-indexed-tree", "array", "hash-table", "ordered-set"], + }, + "1757": { topicTags: ["database"] }, + "1758": { topicTags: ["string"] }, + "1759": { topicTags: ["math", "string"] }, + "1760": { topicTags: ["array", "binary-search"] }, + "1761": { topicTags: ["graph"] }, + "1762": { topicTags: ["stack", "array", "monotonic-stack"] }, + "1763": { + topicTags: ["bit-manipulation", "hash-table", "string", "divide-and-conquer", "sliding-window"], + }, + "1764": { topicTags: ["greedy", "array", "string-matching"] }, + "1765": { topicTags: ["breadth-first-search", "array", "matrix"] }, + "1766": { + topicTags: ["tree", "depth-first-search", "breadth-first-search", "math"], + }, + "1767": { topicTags: ["database"] }, + "1768": { topicTags: ["two-pointers", "string"] }, + "1769": { topicTags: ["array", "string"] }, + "1770": { topicTags: ["array", "dynamic-programming"] }, + "1771": { topicTags: ["string", "dynamic-programming"] }, + "1772": { topicTags: ["array", "hash-table", "string", "sorting"] }, + "1773": { topicTags: ["array", "string"] }, + "1774": { topicTags: ["array", "dynamic-programming", "backtracking"] }, + "1775": { topicTags: ["greedy", "array", "hash-table", "counting"] }, + "1776": { + topicTags: ["stack", "array", "math", "monotonic-stack", "heap-priority-queue"], + }, + "1777": { topicTags: ["database"] }, + "1778": { + topicTags: ["depth-first-search", "breadth-first-search", "graph", "interactive"], + }, + "1779": { topicTags: ["array"] }, + "1780": { topicTags: ["math"] }, + "1781": { topicTags: ["hash-table", "string", "counting"] }, + "1782": { topicTags: ["graph", "two-pointers", "binary-search"] }, + "1783": { topicTags: ["database"] }, + "1784": { topicTags: ["string"] }, + "1785": { topicTags: ["greedy", "array"] }, + "1786": { + topicTags: ["graph", "topological-sort", "dynamic-programming", "shortest-path", "heap-priority-queue"], + }, + "1787": { topicTags: ["bit-manipulation", "array", "dynamic-programming"] }, + "1788": { topicTags: ["greedy", "array", "prefix-sum"] }, + "1789": { topicTags: ["database"] }, + "1790": { topicTags: ["hash-table", "string", "counting"] }, + "1791": { topicTags: ["graph"] }, + "1792": { topicTags: ["greedy", "array", "heap-priority-queue"] }, + "1793": { + topicTags: ["stack", "array", "two-pointers", "binary-search", "monotonic-stack"], + }, + "1794": { topicTags: ["greedy", "hash-table", "string"] }, + "1795": { topicTags: ["database"] }, + "1796": { topicTags: ["hash-table", "string"] }, + "1797": { topicTags: ["design", "hash-table"] }, + "1798": { topicTags: ["greedy", "array"] }, + "1799": { + topicTags: [ + "bit-manipulation", + "array", + "math", + "dynamic-programming", + "backtracking", + "bitmask", + "number-theory", + ], + }, + "1800": { topicTags: ["array"] }, + "1801": { topicTags: ["array", "simulation", "heap-priority-queue"] }, + "1802": { topicTags: ["greedy", "binary-search"] }, + "1803": { topicTags: ["bit-manipulation", "trie", "array"] }, + "1804": { topicTags: ["design", "trie", "hash-table", "string"] }, + "1805": { topicTags: ["hash-table", "string"] }, + "1806": { topicTags: ["array", "math", "simulation"] }, + "1807": { topicTags: ["array", "hash-table", "string"] }, + "1808": { topicTags: ["recursion", "math"] }, + "1809": { topicTags: ["database"] }, + "1810": { + topicTags: ["depth-first-search", "breadth-first-search", "graph", "interactive", "heap-priority-queue"], + }, + "1811": { topicTags: ["database"] }, + "1812": { topicTags: ["math", "string"] }, + "1813": { topicTags: ["array", "two-pointers", "string"] }, + "1814": { topicTags: ["array", "hash-table", "math", "counting"] }, + "1815": { + topicTags: ["bit-manipulation", "memoization", "array", "dynamic-programming", "bitmask"], + }, + "1816": { topicTags: ["array", "string"] }, + "1817": { topicTags: ["array", "hash-table"] }, + "1818": { topicTags: ["array", "binary-search", "ordered-set", "sorting"] }, + "1819": { topicTags: ["array", "math", "counting", "number-theory"] }, + "1820": { topicTags: ["array", "backtracking", "matrix"] }, + "1821": { topicTags: ["database"] }, + "1822": { topicTags: ["array", "math"] }, + "1823": { + topicTags: ["recursion", "queue", "array", "math", "simulation"], + }, + "1824": { topicTags: ["greedy", "array", "dynamic-programming"] }, + "1825": { + topicTags: ["design", "queue", "data-stream", "ordered-set", "heap-priority-queue"], + }, + "1826": { topicTags: ["array", "two-pointers"] }, + "1827": { topicTags: ["greedy", "array"] }, + "1828": { topicTags: ["geometry", "array", "math"] }, + "1829": { topicTags: ["bit-manipulation", "array", "prefix-sum"] }, + "1830": { topicTags: ["math", "string", "combinatorics"] }, + "1831": { topicTags: ["database"] }, + "1832": { topicTags: ["hash-table", "string"] }, + "1833": { topicTags: ["greedy", "array", "sorting"] }, + "1834": { topicTags: ["array", "sorting", "heap-priority-queue"] }, + "1835": { topicTags: ["bit-manipulation", "array", "math"] }, + "1836": { topicTags: ["hash-table", "linked-list"] }, + "1837": { topicTags: ["math"] }, + "1838": { + topicTags: ["array", "binary-search", "prefix-sum", "sliding-window"], + }, + "1839": { topicTags: ["string", "sliding-window"] }, + "1840": { topicTags: ["array", "math"] }, + "1841": { topicTags: ["database"] }, + "1842": { topicTags: ["two-pointers", "string"] }, + "1843": { topicTags: ["database"] }, + "1844": { topicTags: ["string"] }, + "1845": { topicTags: ["design", "heap-priority-queue"] }, + "1846": { topicTags: ["greedy", "array", "sorting"] }, + "1847": { topicTags: ["array", "binary-search", "sorting"] }, + "1848": { topicTags: ["array"] }, + "1849": { topicTags: ["string", "backtracking"] }, + "1850": { topicTags: ["greedy", "two-pointers", "string"] }, + "1851": { + topicTags: ["array", "binary-search", "sorting", "line-sweep", "heap-priority-queue"], + }, + "1852": { topicTags: ["array", "hash-table", "sliding-window"] }, + "1853": { topicTags: ["database"] }, + "1854": { topicTags: ["array", "counting"] }, + "1855": { topicTags: ["greedy", "array", "two-pointers", "binary-search"] }, + "1856": { topicTags: ["stack", "array", "prefix-sum", "monotonic-stack"] }, + "1857": { + topicTags: ["graph", "topological-sort", "memoization", "hash-table", "dynamic-programming", "counting"], + }, + "1858": { topicTags: ["depth-first-search", "trie"] }, + "1859": { topicTags: ["string", "sorting"] }, + "1860": { topicTags: ["simulation"] }, + "1861": { topicTags: ["array", "two-pointers", "matrix"] }, + "1862": { topicTags: ["array", "math", "binary-search", "prefix-sum"] }, + "1863": { + topicTags: ["bit-manipulation", "array", "math", "backtracking", "combinatorics"], + }, + "1864": { topicTags: ["greedy", "string"] }, + "1865": { topicTags: ["design", "array", "hash-table"] }, + "1866": { topicTags: ["math", "dynamic-programming", "combinatorics"] }, + "1867": { topicTags: ["database"] }, + "1868": { topicTags: ["array", "two-pointers"] }, + "1869": { topicTags: ["string"] }, + "1870": { topicTags: ["array", "binary-search"] }, + "1871": { topicTags: ["two-pointers", "string", "prefix-sum"] }, + "1872": { + topicTags: ["array", "math", "dynamic-programming", "game-theory", "prefix-sum"], + }, + "1873": { topicTags: ["database"] }, + "1874": { topicTags: ["greedy", "array", "sorting"] }, + "1875": { topicTags: ["database"] }, + "1876": { + topicTags: ["hash-table", "string", "counting", "sliding-window"], + }, + "1877": { topicTags: ["greedy", "array", "two-pointers", "sorting"] }, + "1878": { + topicTags: ["array", "math", "matrix", "prefix-sum", "sorting", "heap-priority-queue"], + }, + "1879": { + topicTags: ["bit-manipulation", "array", "dynamic-programming", "bitmask"], + }, + "1880": { topicTags: ["string"] }, + "1881": { topicTags: ["greedy", "string"] }, + "1882": { topicTags: ["array", "heap-priority-queue"] }, + "1883": { topicTags: ["array", "dynamic-programming"] }, + "1884": { topicTags: ["math", "dynamic-programming"] }, + "1885": { topicTags: ["array", "binary-search", "sorting"] }, + "1886": { topicTags: ["array", "matrix"] }, + "1887": { topicTags: ["array", "sorting"] }, + "1888": { + topicTags: ["greedy", "string", "dynamic-programming", "sliding-window"], + }, + "1889": { topicTags: ["array", "binary-search", "prefix-sum", "sorting"] }, + "1890": { topicTags: ["database"] }, + "1891": { topicTags: ["array", "binary-search"] }, + "1892": { topicTags: ["database"] }, + "1893": { topicTags: ["array", "hash-table", "prefix-sum"] }, + "1894": { + topicTags: ["array", "binary-search", "prefix-sum", "simulation"], + }, + "1895": { topicTags: ["array", "matrix", "prefix-sum"] }, + "1896": { topicTags: ["stack", "math", "string", "dynamic-programming"] }, + "1897": { topicTags: ["hash-table", "string", "counting"] }, + "1898": { topicTags: ["array", "string", "binary-search"] }, + "1899": { topicTags: ["greedy", "array"] }, + "1900": { topicTags: ["memoization", "dynamic-programming"] }, + "1901": { topicTags: ["array", "binary-search", "matrix"] }, + "1902": { + topicTags: ["tree", "binary-search-tree", "binary-tree", "ordered-set"], + }, + "1903": { topicTags: ["greedy", "math", "string"] }, + "1904": { topicTags: ["math", "string"] }, + "1905": { + topicTags: ["depth-first-search", "breadth-first-search", "union-find", "array", "matrix"], + }, + "1906": { topicTags: ["array", "hash-table"] }, + "1907": { topicTags: ["database"] }, + "1908": { + topicTags: ["bit-manipulation", "brainteaser", "array", "math", "dynamic-programming", "game-theory"], + }, + "1909": { topicTags: ["array"] }, + "1910": { topicTags: ["string"] }, + "1911": { topicTags: ["array", "dynamic-programming"] }, + "1912": { + topicTags: ["design", "array", "hash-table", "ordered-set", "heap-priority-queue"], + }, + "1913": { topicTags: ["array", "sorting"] }, + "1914": { topicTags: ["array", "matrix", "simulation"] }, + "1915": { + topicTags: ["bit-manipulation", "hash-table", "string", "prefix-sum"], + }, + "1916": { + topicTags: ["tree", "graph", "topological-sort", "math", "dynamic-programming", "combinatorics"], + }, + "1917": { topicTags: ["database"] }, + "1918": { topicTags: ["array", "binary-search", "sliding-window"] }, + "1919": { topicTags: ["database"] }, + "1920": { topicTags: ["array", "simulation"] }, + "1921": { topicTags: ["greedy", "array", "sorting"] }, + "1922": { topicTags: ["recursion", "math"] }, + "1923": { + topicTags: ["array", "binary-search", "suffix-array", "hash-function", "rolling-hash"], + }, + "1924": { topicTags: ["geometry", "array", "math"] }, + "1925": { topicTags: ["math", "enumeration"] }, + "1926": { topicTags: ["breadth-first-search", "array", "matrix"] }, + "1927": { topicTags: ["greedy", "math", "game-theory"] }, + "1928": { topicTags: ["graph", "dynamic-programming"] }, + "1929": { topicTags: ["array"] }, + "1930": { topicTags: ["hash-table", "string", "prefix-sum"] }, + "1931": { topicTags: ["dynamic-programming"] }, + "1932": { + topicTags: ["tree", "depth-first-search", "hash-table", "binary-search", "binary-tree"], + }, + "1933": { topicTags: ["string"] }, + "1934": { topicTags: ["database"] }, + "1935": { topicTags: ["hash-table", "string"] }, + "1936": { topicTags: ["greedy", "array"] }, + "1937": { topicTags: [] }, + "1938": { topicTags: [] }, + "1939": { topicTags: ["database"] }, + "1940": { topicTags: ["array", "hash-table", "counting"] }, + "1941": { topicTags: ["hash-table", "string", "counting"] }, + "1942": { topicTags: ["array", "ordered-set", "heap-priority-queue"] }, + "1943": { topicTags: ["array", "prefix-sum"] }, + "1944": { topicTags: ["stack", "array", "monotonic-stack"] }, + "1945": { topicTags: ["string", "simulation"] }, + "1946": { topicTags: ["greedy", "array", "string"] }, + "1947": { + topicTags: ["bit-manipulation", "array", "dynamic-programming", "backtracking", "bitmask"], + }, + "1948": { + topicTags: ["trie", "array", "hash-table", "string", "hash-function"], + }, + "1949": { topicTags: ["database"] }, + "1950": { topicTags: ["stack", "array", "monotonic-stack"] }, + "1951": { topicTags: ["database"] }, + "1952": { topicTags: ["math"] }, + "1953": { topicTags: ["greedy", "array"] }, + "1954": { topicTags: ["math", "binary-search"] }, + "1955": { topicTags: ["array", "dynamic-programming"] }, + "1956": { + topicTags: ["geometry", "array", "math", "binary-search", "enumeration"], + }, + "1957": { topicTags: ["string"] }, + "1958": { topicTags: ["array", "enumeration", "matrix"] }, + "1959": { topicTags: ["array", "dynamic-programming"] }, + "1960": { topicTags: ["string", "hash-function", "rolling-hash"] }, + "1961": { topicTags: ["array", "string"] }, + "1962": { topicTags: ["array", "heap-priority-queue"] }, + "1963": { topicTags: ["stack", "greedy", "two-pointers", "string"] }, + "1964": { topicTags: ["binary-indexed-tree", "array", "binary-search"] }, + "1965": { topicTags: ["database"] }, + "1966": { topicTags: ["array", "binary-search"] }, + "1967": { topicTags: ["string"] }, + "1968": { topicTags: ["greedy", "array", "sorting"] }, + "1969": { topicTags: ["greedy", "recursion", "math"] }, + "1970": { + topicTags: ["depth-first-search", "breadth-first-search", "union-find", "array", "binary-search", "matrix"], + }, + "1971": { + topicTags: ["depth-first-search", "breadth-first-search", "union-find", "graph"], + }, + "1972": { topicTags: ["database"] }, + "1973": { topicTags: [] }, + "1974": { topicTags: ["greedy", "string"] }, + "1975": { topicTags: ["greedy", "array", "matrix"] }, + "1976": { + topicTags: ["graph", "topological-sort", "dynamic-programming", "shortest-path"], + }, + "1977": { topicTags: ["string", "dynamic-programming", "suffix-array"] }, + "1978": { topicTags: [] }, + "1979": { topicTags: ["array", "math", "number-theory"] }, + "1980": { topicTags: ["array", "string", "backtracking"] }, + "1981": { topicTags: ["array", "dynamic-programming", "matrix"] }, + "1982": { topicTags: ["array", "divide-and-conquer"] }, + "1983": { topicTags: ["array", "hash-table", "prefix-sum"] }, + "1984": { topicTags: ["array", "sorting", "sliding-window"] }, + "1985": { + topicTags: ["array", "string", "divide-and-conquer", "quickselect", "sorting", "heap-priority-queue"], + }, + "1986": { + topicTags: ["bit-manipulation", "array", "dynamic-programming", "backtracking", "bitmask"], + }, + "1987": { topicTags: ["string", "dynamic-programming"] }, + "1988": { topicTags: [] }, + "1989": { topicTags: [] }, + "1990": { topicTags: [] }, + "1991": { topicTags: ["array", "prefix-sum"] }, + "1992": { + topicTags: ["depth-first-search", "breadth-first-search", "array", "matrix"], + }, + "1993": { + topicTags: ["tree", "depth-first-search", "breadth-first-search", "design", "hash-table"], + }, + "1994": { + topicTags: ["bit-manipulation", "array", "math", "dynamic-programming", "bitmask"], + }, + "1995": { topicTags: ["array", "enumeration"] }, + "1996": { + topicTags: ["stack", "greedy", "array", "sorting", "monotonic-stack"], + }, + "1997": { topicTags: ["array", "dynamic-programming"] }, + "1998": { topicTags: ["union-find", "array", "math", "sorting"] }, + "1999": { topicTags: [] }, + "2000": { topicTags: ["two-pointers", "string"] }, + "2001": { + topicTags: ["array", "hash-table", "math", "counting", "number-theory"], + }, + "2002": { + topicTags: ["bit-manipulation", "string", "dynamic-programming", "backtracking", "bitmask"], + }, + "2003": { + topicTags: ["tree", "depth-first-search", "union-find", "dynamic-programming"], + }, + "2004": { topicTags: [] }, + "2005": { topicTags: [] }, + "2006": { topicTags: ["array", "hash-table", "counting"] }, + "2007": { topicTags: ["greedy", "array", "hash-table", "sorting"] }, + "2008": { + topicTags: ["array", "binary-search", "dynamic-programming", "sorting"], + }, + "2009": { topicTags: ["array", "binary-search"] }, + "2010": { topicTags: [] }, + "2011": { topicTags: ["array", "string", "simulation"] }, + "2012": { topicTags: ["array"] }, + "2013": { topicTags: ["design", "array", "hash-table", "counting"] }, + "2014": { + topicTags: ["greedy", "string", "backtracking", "counting", "enumeration"], + }, + "2015": { + topicTags: ["greedy", "array", "sorting", "heap-priority-queue"], + }, + "2016": { topicTags: ["array"] }, + "2017": { topicTags: ["array", "matrix", "prefix-sum"] }, + "2018": { topicTags: ["array", "enumeration", "matrix"] }, + "2019": { + topicTags: ["stack", "memoization", "array", "math", "string", "dynamic-programming"], + }, + "2020": { topicTags: ["database"] }, + "2021": { topicTags: ["array", "ordered-set", "prefix-sum"] }, + "2022": { topicTags: ["array", "matrix", "simulation"] }, + "2023": { topicTags: ["array", "string"] }, + "2024": { + topicTags: ["string", "binary-search", "prefix-sum", "sliding-window"], + }, + "2025": { + topicTags: ["array", "hash-table", "counting", "enumeration", "prefix-sum"], + }, + "2026": { topicTags: ["database"] }, + "2027": { topicTags: ["greedy", "string"] }, + "2028": { topicTags: ["array", "math", "simulation"] }, + "2029": { + topicTags: ["greedy", "array", "math", "counting", "game-theory"], + }, + "2030": { topicTags: ["stack", "greedy", "string", "monotonic-stack"] }, + "2031": { + topicTags: [ + "binary-indexed-tree", + "segment-tree", + "array", + "binary-search", + "divide-and-conquer", + "ordered-set", + "merge-sort", + ], + }, + "2032": { topicTags: ["array", "hash-table"] }, + "2033": { topicTags: ["array", "math", "matrix", "sorting"] }, + "2034": { + topicTags: ["design", "hash-table", "data-stream", "ordered-set", "heap-priority-queue"], + }, + "2035": { + topicTags: [ + "bit-manipulation", + "array", + "two-pointers", + "binary-search", + "dynamic-programming", + "bitmask", + "ordered-set", + ], + }, + "2036": { topicTags: ["array", "dynamic-programming"] }, + "2037": { topicTags: ["array", "sorting"] }, + "2038": { topicTags: ["greedy", "math", "string", "game-theory"] }, + "2039": { topicTags: ["breadth-first-search", "graph", "array"] }, + "2040": { topicTags: ["array", "binary-search"] }, + "2041": { topicTags: ["database"] }, + "2042": { topicTags: ["string"] }, + "2043": { topicTags: ["design", "array", "hash-table", "simulation"] }, + "2044": { topicTags: ["bit-manipulation", "array", "backtracking"] }, + "2045": { topicTags: ["breadth-first-search", "graph", "shortest-path"] }, + "2046": { topicTags: ["linked-list", "two-pointers", "sorting"] }, + "2047": { topicTags: ["string"] }, + "2048": { topicTags: ["math", "backtracking", "enumeration"] }, + "2049": { + topicTags: ["tree", "depth-first-search", "array", "binary-tree"], + }, + "2050": { topicTags: ["graph", "topological-sort", "dynamic-programming"] }, + "2051": { topicTags: ["database"] }, + "2052": { topicTags: ["array", "dynamic-programming"] }, + "2053": { topicTags: ["array", "hash-table", "string", "counting"] }, + "2054": { + topicTags: ["array", "binary-search", "dynamic-programming", "sorting", "heap-priority-queue"], + }, + "2055": { topicTags: ["array", "string", "binary-search", "prefix-sum"] }, + "2056": { topicTags: ["array", "string", "backtracking", "simulation"] }, + "2057": { topicTags: ["array"] }, + "2058": { topicTags: ["linked-list"] }, + "2059": { topicTags: ["breadth-first-search", "array"] }, + "2060": { topicTags: ["string", "dynamic-programming"] }, + "2061": { topicTags: ["array", "matrix", "simulation"] }, + "2062": { topicTags: ["hash-table", "string"] }, + "2063": { + topicTags: ["math", "string", "dynamic-programming", "combinatorics"], + }, + "2064": { topicTags: ["array", "binary-search"] }, + "2065": { topicTags: ["graph", "array", "backtracking"] }, + "2066": { topicTags: ["database"] }, + "2067": { topicTags: ["string", "counting", "prefix-sum"] }, + "2068": { topicTags: ["hash-table", "string", "counting"] }, + "2069": { topicTags: ["design", "simulation"] }, + "2070": { topicTags: ["array", "binary-search", "sorting"] }, + "2071": { + topicTags: ["greedy", "queue", "array", "binary-search", "sorting", "monotonic-queue"], + }, + "2072": { topicTags: ["database"] }, + "2073": { topicTags: ["queue", "array", "simulation"] }, + "2074": { topicTags: ["linked-list"] }, + "2075": { topicTags: ["string", "simulation"] }, + "2076": { topicTags: ["union-find", "graph"] }, + "2077": { topicTags: ["graph"] }, + "2078": { topicTags: ["greedy", "array"] }, + "2079": { topicTags: ["array"] }, + "2080": { + topicTags: ["design", "segment-tree", "array", "hash-table", "binary-search"], + }, + "2081": { topicTags: ["math", "enumeration"] }, + "2082": { topicTags: ["database"] }, + "2083": { + topicTags: ["hash-table", "math", "string", "counting", "prefix-sum"], + }, + "2084": { topicTags: ["database"] }, + "2085": { topicTags: ["array", "hash-table", "string", "counting"] }, + "2086": { topicTags: ["greedy", "string", "dynamic-programming"] }, + "2087": { topicTags: ["greedy", "array", "matrix"] }, + "2088": { topicTags: ["array", "dynamic-programming", "matrix"] }, + "2089": { topicTags: ["array", "binary-search", "sorting"] }, + "2090": { topicTags: ["array", "sliding-window"] }, + "2091": { topicTags: ["greedy", "array"] }, + "2092": { + topicTags: ["depth-first-search", "breadth-first-search", "union-find", "graph", "sorting"], + }, + "2093": { topicTags: ["graph", "shortest-path"] }, + "2094": { topicTags: ["array", "hash-table", "enumeration", "sorting"] }, + "2095": { topicTags: ["linked-list", "two-pointers"] }, + "2096": { + topicTags: ["tree", "depth-first-search", "string", "binary-tree"], + }, + "2097": { topicTags: ["depth-first-search", "graph", "eulerian-circuit"] }, + "2098": { topicTags: ["greedy", "array", "sorting"] }, + "2099": { + topicTags: ["array", "hash-table", "sorting", "heap-priority-queue"], + }, + "2100": { topicTags: ["array", "dynamic-programming", "prefix-sum"] }, + "2101": { + topicTags: ["depth-first-search", "breadth-first-search", "graph", "geometry", "array", "math"], + }, + "2102": { + topicTags: ["design", "data-stream", "ordered-set", "heap-priority-queue"], + }, + "2103": { topicTags: ["hash-table", "string"] }, + "2104": { topicTags: ["stack", "array", "monotonic-stack"] }, + "2105": { topicTags: ["array", "two-pointers", "simulation"] }, + "2106": { + topicTags: ["array", "binary-search", "prefix-sum", "sliding-window"], + }, + "2107": { topicTags: ["array", "hash-table", "sliding-window"] }, + "2108": { topicTags: ["array", "two-pointers", "string"] }, + "2109": { topicTags: ["array", "string", "simulation"] }, + "2110": { topicTags: ["array", "math", "dynamic-programming"] }, + "2111": { topicTags: ["array", "binary-search"] }, + "2112": { topicTags: ["database"] }, + "2113": { topicTags: ["array"] }, + "2114": { topicTags: ["array", "string"] }, + "2115": { + topicTags: ["graph", "topological-sort", "array", "hash-table", "string"], + }, + "2116": { topicTags: ["stack", "greedy", "string"] }, + "2117": { topicTags: ["math"] }, + "2118": { topicTags: ["database"] }, + "2119": { topicTags: ["math"] }, + "2120": { topicTags: ["string", "simulation"] }, + "2121": { topicTags: ["array", "hash-table", "prefix-sum"] }, + "2122": { topicTags: ["array", "hash-table", "enumeration", "sorting"] }, + "2123": { topicTags: ["graph", "array", "matrix"] }, + "2124": { topicTags: ["string"] }, + "2125": { topicTags: ["array", "math", "string", "matrix"] }, + "2126": { topicTags: ["greedy", "array", "sorting"] }, + "2127": { topicTags: ["depth-first-search", "graph", "topological-sort"] }, + "2128": { topicTags: ["bit-manipulation", "array", "math", "matrix"] }, + "2129": { topicTags: ["string"] }, + "2130": { topicTags: ["stack", "linked-list", "two-pointers"] }, + "2131": { + topicTags: ["greedy", "array", "hash-table", "string", "counting"], + }, + "2132": { topicTags: ["greedy", "array", "matrix", "prefix-sum"] }, + "2133": { topicTags: ["array", "hash-table", "matrix"] }, + "2134": { topicTags: ["array", "sliding-window"] }, + "2135": { + topicTags: ["bit-manipulation", "array", "hash-table", "string", "sorting"], + }, + "2136": { topicTags: ["greedy", "array", "sorting"] }, + "2137": { topicTags: ["array", "binary-search"] }, + "2138": { topicTags: ["string", "simulation"] }, + "2139": { topicTags: ["greedy", "math"] }, + "2140": { topicTags: ["array", "dynamic-programming"] }, + "2141": { topicTags: ["greedy", "array", "binary-search", "sorting"] }, + "2142": { topicTags: ["database"] }, + "2143": { topicTags: ["array", "dynamic-programming"] }, + "2144": { topicTags: ["greedy", "array", "sorting"] }, + "2145": { topicTags: ["array", "prefix-sum"] }, + "2146": { + topicTags: ["breadth-first-search", "array", "matrix", "sorting", "heap-priority-queue"], + }, + "2147": { topicTags: ["math", "string", "dynamic-programming"] }, + "2148": { topicTags: ["array", "sorting"] }, + "2149": { topicTags: ["array", "two-pointers", "simulation"] }, + "2150": { topicTags: ["array", "hash-table", "counting"] }, + "2151": { + topicTags: ["bit-manipulation", "array", "backtracking", "enumeration"], + }, + "2152": { + topicTags: [ + "bit-manipulation", + "geometry", + "array", + "hash-table", + "math", + "dynamic-programming", + "backtracking", + "bitmask", + ], + }, + "2153": { topicTags: ["database"] }, + "2154": { topicTags: ["array", "hash-table", "sorting", "simulation"] }, + "2155": { topicTags: ["array"] }, + "2156": { + topicTags: ["string", "sliding-window", "hash-function", "rolling-hash"], + }, + "2157": { topicTags: ["bit-manipulation", "union-find", "string"] }, + "2158": { topicTags: ["segment-tree", "array", "ordered-set"] }, + "2159": { topicTags: ["database"] }, + "2160": { topicTags: ["greedy", "math", "sorting"] }, + "2161": { topicTags: ["array", "two-pointers", "simulation"] }, + "2162": { topicTags: ["math", "enumeration"] }, + "2163": { + topicTags: ["array", "dynamic-programming", "heap-priority-queue"], + }, + "2164": { topicTags: ["array", "sorting"] }, + "2165": { topicTags: ["math", "sorting"] }, + "2166": { topicTags: ["design", "array", "hash-table"] }, + "2167": { topicTags: ["string", "dynamic-programming"] }, + "2168": { + topicTags: ["hash-table", "string", "counting", "hash-function", "rolling-hash"], + }, + "2169": { topicTags: ["math", "simulation"] }, + "2170": { topicTags: ["greedy", "array", "hash-table", "counting"] }, + "2171": { topicTags: ["array", "prefix-sum", "sorting"] }, + "2172": { + topicTags: ["bit-manipulation", "array", "dynamic-programming", "bitmask"], + }, + "2173": { topicTags: ["database"] }, + "2174": { + topicTags: ["bit-manipulation", "breadth-first-search", "array", "matrix"], + }, + "2175": { topicTags: ["database"] }, + "2176": { topicTags: ["array"] }, + "2177": { topicTags: ["math", "simulation"] }, + "2178": { topicTags: ["greedy", "math", "backtracking"] }, + "2179": { + topicTags: [ + "binary-indexed-tree", + "segment-tree", + "array", + "binary-search", + "divide-and-conquer", + "ordered-set", + "merge-sort", + ], + }, + "2180": { topicTags: ["math", "simulation"] }, + "2181": { topicTags: ["linked-list", "simulation"] }, + "2182": { + topicTags: ["greedy", "string", "counting", "heap-priority-queue"], + }, + "2183": { topicTags: ["array", "math", "number-theory"] }, + "2184": { + topicTags: ["bit-manipulation", "array", "dynamic-programming", "bitmask"], + }, + "2185": { topicTags: ["array", "string"] }, + "2186": { topicTags: ["hash-table", "string", "counting"] }, + "2187": { topicTags: ["array", "binary-search"] }, + "2188": { topicTags: ["array", "dynamic-programming"] }, + "2189": { topicTags: ["math", "dynamic-programming"] }, + "2190": { topicTags: ["array", "hash-table", "counting"] }, + "2191": { topicTags: ["array", "sorting"] }, + "2192": { + topicTags: ["depth-first-search", "breadth-first-search", "graph", "topological-sort"], + }, + "2193": { + topicTags: ["greedy", "binary-indexed-tree", "two-pointers", "string"], + }, + "2194": { topicTags: ["string"] }, + "2195": { topicTags: ["greedy", "array", "math", "sorting"] }, + "2196": { + topicTags: ["tree", "depth-first-search", "breadth-first-search", "array", "hash-table", "binary-tree"], + }, + "2197": { topicTags: ["stack", "array", "math", "number-theory"] }, + "2198": { topicTags: ["math"] }, + "2199": { topicTags: ["database"] }, + "2200": { topicTags: ["array"] }, + "2201": { topicTags: ["array", "hash-table", "simulation"] }, + "2202": { topicTags: ["greedy", "array"] }, + "2203": { topicTags: ["graph", "shortest-path"] }, + "2204": { + topicTags: ["depth-first-search", "breadth-first-search", "union-find", "graph"], + }, + "2205": { topicTags: ["database"] }, + "2206": { + topicTags: ["bit-manipulation", "array", "hash-table", "counting"], + }, + "2207": { topicTags: ["greedy", "string", "prefix-sum"] }, + "2208": { topicTags: ["greedy", "array", "heap-priority-queue"] }, + "2209": { topicTags: ["string", "dynamic-programming", "prefix-sum"] }, + "2210": { topicTags: ["array"] }, + "2211": { topicTags: ["stack", "string"] }, + "2212": { + topicTags: ["bit-manipulation", "recursion", "array", "enumeration"], + }, + "2213": { topicTags: ["segment-tree", "array", "string", "ordered-set"] }, + "2214": { topicTags: ["greedy", "array", "prefix-sum"] }, + "2215": { topicTags: ["array", "hash-table"] }, + "2216": { topicTags: ["stack", "greedy", "array"] }, + "2217": { topicTags: ["array", "math"] }, + "2218": { topicTags: ["array", "dynamic-programming", "prefix-sum"] }, + "2219": { topicTags: ["array", "prefix-sum"] }, + "2220": { topicTags: ["bit-manipulation"] }, + "2221": { topicTags: ["array", "math", "combinatorics", "simulation"] }, + "2222": { topicTags: ["string", "dynamic-programming", "prefix-sum"] }, + "2223": { + topicTags: ["string", "binary-search", "string-matching", "suffix-array", "hash-function", "rolling-hash"], + }, + "2224": { topicTags: ["greedy", "string"] }, + "2225": { topicTags: ["array", "hash-table", "counting", "sorting"] }, + "2226": { topicTags: ["array", "binary-search"] }, + "2227": { topicTags: ["design", "trie", "array", "hash-table", "string"] }, + "2228": { topicTags: ["database"] }, + "2229": { topicTags: ["array"] }, + "2230": { topicTags: ["database"] }, + "2231": { topicTags: ["sorting", "heap-priority-queue"] }, + "2232": { topicTags: ["string", "enumeration"] }, + "2233": { topicTags: ["greedy", "array", "heap-priority-queue"] }, + "2234": { + topicTags: ["greedy", "array", "two-pointers", "binary-search", "sorting"], + }, + "2235": { topicTags: ["math"] }, + "2236": { topicTags: ["tree", "binary-tree"] }, + "2237": { topicTags: ["array", "prefix-sum"] }, + "2238": { topicTags: ["database"] }, + "2239": { topicTags: ["array"] }, + "2240": { topicTags: ["math", "enumeration"] }, + "2241": { topicTags: ["greedy", "design", "array"] }, + "2242": { topicTags: ["graph", "array", "enumeration", "sorting"] }, + "2243": { topicTags: ["string", "simulation"] }, + "2244": { topicTags: ["greedy", "array", "hash-table", "counting"] }, + "2245": { topicTags: ["array", "matrix", "prefix-sum"] }, + "2246": { + topicTags: ["tree", "depth-first-search", "graph", "topological-sort", "array", "string"], + }, + "2247": { + topicTags: ["bit-manipulation", "graph", "dynamic-programming", "bitmask"], + }, + "2248": { topicTags: ["array", "hash-table", "counting"] }, + "2249": { + topicTags: ["geometry", "array", "hash-table", "math", "enumeration"], + }, + "2250": { + topicTags: ["binary-indexed-tree", "array", "binary-search", "sorting"], + }, + "2251": { + topicTags: ["array", "hash-table", "binary-search", "ordered-set", "prefix-sum", "sorting"], + }, + "2252": { topicTags: ["database"] }, + "2253": { topicTags: ["database"] }, + "2254": { topicTags: ["stack", "design", "hash-table", "ordered-set"] }, + "2255": { topicTags: ["array", "string"] }, + "2256": { topicTags: ["array", "prefix-sum"] }, + "2257": { topicTags: ["array", "matrix", "simulation"] }, + "2258": { + topicTags: ["breadth-first-search", "array", "binary-search", "matrix"], + }, + "2259": { topicTags: ["greedy", "string", "enumeration"] }, + "2260": { topicTags: ["array", "hash-table", "sliding-window"] }, + "2261": { + topicTags: ["trie", "array", "hash-table", "enumeration", "hash-function", "rolling-hash"], + }, + "2262": { topicTags: ["hash-table", "string", "dynamic-programming"] }, + "2263": { topicTags: ["greedy", "dynamic-programming"] }, + "2264": { topicTags: ["string"] }, + "2265": { topicTags: ["tree", "depth-first-search", "binary-tree"] }, + "2266": { + topicTags: ["hash-table", "math", "string", "dynamic-programming"], + }, + "2267": { topicTags: ["array", "dynamic-programming", "matrix"] }, + "2268": { topicTags: ["greedy", "array", "string", "counting", "sorting"] }, + "2269": { topicTags: ["math", "string", "sliding-window"] }, + "2270": { topicTags: [] }, + "2271": { + topicTags: ["greedy", "array", "binary-search", "prefix-sum", "sorting"], + }, + "2272": { topicTags: ["array", "dynamic-programming"] }, + "2273": { topicTags: ["array", "hash-table", "string", "sorting"] }, + "2274": { topicTags: ["array", "sorting"] }, + "2275": { + topicTags: ["bit-manipulation", "array", "hash-table", "counting"], + }, + "2276": { topicTags: ["design", "segment-tree", "ordered-set"] }, + "2277": { + topicTags: ["tree", "depth-first-search", "breadth-first-search", "array"], + }, + "2278": { topicTags: ["string"] }, + "2279": { topicTags: ["greedy", "array", "sorting"] }, + "2280": { + topicTags: ["geometry", "array", "math", "number-theory", "sorting"], + }, + "2281": { topicTags: ["stack", "array", "prefix-sum", "monotonic-stack"] }, + "2282": { topicTags: ["stack", "array", "matrix", "monotonic-stack"] }, + "2283": { topicTags: ["hash-table", "string", "counting"] }, + "2284": { topicTags: ["array", "hash-table", "string", "counting"] }, + "2285": { + topicTags: ["greedy", "graph", "sorting", "heap-priority-queue"], + }, + "2286": { + topicTags: ["design", "binary-indexed-tree", "segment-tree", "binary-search"], + }, + "2287": { topicTags: ["hash-table", "string", "counting"] }, + "2288": { topicTags: ["string"] }, + "2289": { topicTags: ["stack", "array", "linked-list", "monotonic-stack"] }, + "2290": { + topicTags: ["breadth-first-search", "graph", "array", "matrix", "shortest-path", "heap-priority-queue"], + }, + "2291": { topicTags: ["array", "dynamic-programming"] }, + "2292": { topicTags: ["database"] }, + "2293": { topicTags: ["array", "simulation"] }, + "2294": { topicTags: ["greedy", "array", "sorting"] }, + "2295": { topicTags: ["array", "hash-table", "simulation"] }, + "2296": { + topicTags: ["stack", "design", "linked-list", "string", "doubly-linked-list", "simulation"], + }, + "2297": { + topicTags: ["stack", "graph", "array", "dynamic-programming", "shortest-path", "monotonic-stack"], + }, + "2298": { topicTags: ["database"] }, + "2299": { topicTags: ["string"] }, + "2300": { + topicTags: ["array", "two-pointers", "binary-search", "sorting"], + }, + "2301": { topicTags: ["array", "hash-table", "string", "string-matching"] }, + "2302": { + topicTags: ["array", "binary-search", "prefix-sum", "sliding-window"], + }, + "2303": { topicTags: ["array", "simulation"] }, + "2304": { topicTags: ["array", "dynamic-programming", "matrix"] }, + "2305": { + topicTags: ["bit-manipulation", "array", "dynamic-programming", "backtracking", "bitmask"], + }, + "2306": { + topicTags: ["bit-manipulation", "array", "hash-table", "string", "enumeration"], + }, + "2307": { + topicTags: ["depth-first-search", "union-find", "graph", "array"], + }, + "2308": { topicTags: ["database"] }, + "2309": { topicTags: ["hash-table", "string", "enumeration"] }, + "2310": { + topicTags: ["greedy", "math", "dynamic-programming", "enumeration"], + }, + "2311": { + topicTags: ["greedy", "memoization", "string", "dynamic-programming"], + }, + "2312": { topicTags: ["memoization", "array", "dynamic-programming"] }, + "2313": { + topicTags: ["tree", "depth-first-search", "dynamic-programming", "binary-tree"], + }, + "2314": { topicTags: ["database"] }, + "2315": { topicTags: ["string"] }, + "2316": { + topicTags: ["depth-first-search", "breadth-first-search", "union-find", "graph"], + }, + "2317": { topicTags: ["bit-manipulation", "array", "math"] }, + "2318": { topicTags: ["memoization", "dynamic-programming"] }, + "2319": { topicTags: ["array", "matrix"] }, + "2320": { topicTags: ["dynamic-programming"] }, + "2321": { topicTags: ["array", "dynamic-programming"] }, + "2322": { + topicTags: ["bit-manipulation", "tree", "depth-first-search", "array"], + }, + "2323": { topicTags: ["greedy", "array", "sorting"] }, + "2324": { topicTags: ["database"] }, + "2325": { topicTags: ["hash-table", "string"] }, + "2326": { topicTags: ["array", "linked-list", "matrix", "simulation"] }, + "2327": { topicTags: ["queue", "dynamic-programming", "simulation"] }, + "2328": { + topicTags: [ + "depth-first-search", + "breadth-first-search", + "graph", + "topological-sort", + "memoization", + "array", + "dynamic-programming", + "matrix", + ], + }, + "2329": { topicTags: ["database"] }, + "2330": { topicTags: ["two-pointers", "string"] }, + "2331": { topicTags: ["tree", "depth-first-search", "binary-search"] }, + "2332": { + topicTags: ["array", "two-pointers", "binary-search", "sorting"], + }, + "2333": { topicTags: ["array", "math", "sorting", "heap-priority-queue"] }, + "2334": { topicTags: ["stack", "union-find", "array", "monotonic-stack"] }, + "2335": { topicTags: ["greedy", "array", "heap-priority-queue"] }, + "2336": { topicTags: ["design", "hash-table", "heap-priority-queue"] }, + "2337": { topicTags: ["two-pointers", "string"] }, + "2338": { + topicTags: ["math", "dynamic-programming", "combinatorics", "number-theory"], + }, + "2339": { topicTags: ["database"] }, + "2340": { topicTags: ["greedy", "array"] }, + "2341": { topicTags: ["array", "hash-table", "counting"] }, + "2342": { + topicTags: ["array", "hash-table", "sorting", "heap-priority-queue"], + }, + "2343": { + topicTags: [ + "array", + "string", + "divide-and-conquer", + "quickselect", + "radix-sort", + "sorting", + "heap-priority-queue", + ], + }, + "2344": { + topicTags: ["array", "math", "number-theory", "sorting", "heap-priority-queue"], + }, + "2345": { topicTags: ["stack", "array", "sorting", "monotonic-stack"] }, + "2346": { topicTags: ["database"] }, + "2347": { topicTags: ["array", "hash-table", "counting"] }, + "2348": { topicTags: ["array", "math"] }, + "2349": { + topicTags: ["design", "hash-table", "ordered-set", "heap-priority-queue"], + }, + "2350": { topicTags: ["greedy", "array", "hash-table"] }, + "2351": { topicTags: ["hash-table", "string", "counting"] }, + "2352": { topicTags: ["array", "hash-table", "matrix", "simulation"] }, + "2353": { + topicTags: ["design", "hash-table", "ordered-set", "heap-priority-queue"], + }, + "2354": { + topicTags: ["bit-manipulation", "array", "hash-table", "binary-search"], + }, + "2355": { + topicTags: ["stack", "array", "dynamic-programming", "monotonic-stack"], + }, + "2356": { topicTags: ["database"] }, + "2357": { + topicTags: ["array", "hash-table", "sorting", "simulation", "heap-priority-queue"], + }, + "2358": { topicTags: ["greedy", "array", "math", "binary-search"] }, + "2359": { topicTags: ["depth-first-search", "graph"] }, + "2360": { topicTags: ["depth-first-search", "graph", "topological-sort"] }, + "2361": { topicTags: ["array", "dynamic-programming"] }, + "2362": { topicTags: ["database"] }, + "2363": { topicTags: ["array", "hash-table", "ordered-set", "sorting"] }, + "2364": { topicTags: ["array", "hash-table"] }, + "2365": { topicTags: ["array", "hash-table", "simulation"] }, + "2366": { topicTags: ["greedy", "array", "math"] }, + "2367": { + topicTags: ["array", "hash-table", "two-pointers", "enumeration"], + }, + "2368": { + topicTags: ["tree", "depth-first-search", "breadth-first-search", "graph", "array", "hash-table"], + }, + "2369": { topicTags: ["array", "dynamic-programming"] }, + "2370": { topicTags: ["hash-table", "string", "dynamic-programming"] }, + "2371": { + topicTags: ["greedy", "union-find", "graph", "topological-sort", "array", "matrix", "sorting"], + }, + "2372": { topicTags: ["database"] }, + "2373": { topicTags: ["array", "matrix"] }, + "2374": { topicTags: ["graph", "hash-table"] }, + "2375": { topicTags: ["stack", "greedy", "string", "backtracking"] }, + "2376": { topicTags: ["math", "dynamic-programming"] }, + "2377": { topicTags: ["database"] }, + "2378": { + topicTags: ["tree", "depth-first-search", "dynamic-programming"], + }, + "2379": { topicTags: ["string", "sliding-window"] }, + "2380": { topicTags: ["string", "dynamic-programming", "simulation"] }, + "2381": { topicTags: ["array", "string", "prefix-sum"] }, + "2382": { topicTags: ["union-find", "array", "ordered-set", "prefix-sum"] }, + "2383": { topicTags: ["greedy", "array"] }, + "2384": { topicTags: ["greedy", "hash-table", "string"] }, + "2385": { + topicTags: ["tree", "depth-first-search", "breadth-first-search", "binary-tree"], + }, + "2386": { topicTags: ["array", "sorting", "heap-priority-queue"] }, + "2387": { topicTags: ["array", "binary-search", "matrix"] }, + "2388": { topicTags: ["database"] }, + "2389": { + topicTags: ["greedy", "array", "binary-search", "prefix-sum", "sorting"], + }, + "2390": { topicTags: ["stack", "string", "simulation"] }, + "2391": { topicTags: ["array", "string", "prefix-sum"] }, + "2392": { topicTags: ["graph", "topological-sort", "array", "matrix"] }, + "2393": { topicTags: ["array", "math", "dynamic-programming"] }, + "2394": { topicTags: ["database"] }, + "2395": { topicTags: ["array", "hash-table"] }, + "2396": { topicTags: ["brainteaser", "math", "two-pointers"] }, + "2397": { + topicTags: ["bit-manipulation", "array", "backtracking", "enumeration", "matrix"], + }, + "2398": { + topicTags: ["queue", "array", "binary-search", "prefix-sum", "sliding-window", "heap-priority-queue"], + }, + "2399": { topicTags: ["array", "hash-table", "string"] }, + "2400": { topicTags: ["math", "dynamic-programming", "combinatorics"] }, + "2401": { topicTags: ["bit-manipulation", "array", "sliding-window"] }, + "2402": { topicTags: ["array", "sorting", "heap-priority-queue"] }, + "2403": { + topicTags: ["bit-manipulation", "array", "dynamic-programming", "bitmask"], + }, + "2404": { topicTags: ["array", "hash-table", "counting"] }, + "2405": { topicTags: ["greedy", "hash-table", "string"] }, + "2406": { + topicTags: ["greedy", "array", "two-pointers", "prefix-sum", "sorting", "heap-priority-queue"], + }, + "2407": { + topicTags: [ + "binary-indexed-tree", + "segment-tree", + "queue", + "array", + "divide-and-conquer", + "dynamic-programming", + "monotonic-queue", + ], + }, + "2408": { topicTags: ["design", "array", "hash-table", "string"] }, + "2409": { topicTags: ["math", "string"] }, + "2410": { topicTags: ["greedy", "array", "two-pointers", "sorting"] }, + "2411": { + topicTags: ["bit-manipulation", "array", "binary-search", "sliding-window"], + }, + "2412": { topicTags: ["greedy", "array", "sorting"] }, + "2413": { topicTags: ["math", "number-theory"] }, + "2414": { topicTags: ["string"] }, + "2415": { + topicTags: ["tree", "depth-first-search", "breadth-first-search", "binary-tree"], + }, + "2416": { topicTags: ["trie", "array", "string", "counting"] }, + "2417": { topicTags: ["math", "enumeration"] }, + "2418": { topicTags: ["array", "hash-table", "string", "sorting"] }, + "2419": { topicTags: ["bit-manipulation", "brainteaser", "array"] }, + "2420": { topicTags: ["array", "dynamic-programming", "prefix-sum"] }, + "2421": { topicTags: ["tree", "union-find", "graph", "array"] }, + "LCP 01": { topicTags: ["array"] }, + "LCP 02": { topicTags: ["array", "math", "number-theory", "simulation"] }, + "LCP 03": { topicTags: ["array", "hash-table", "simulation"] }, + "LCP 04": { + topicTags: ["bit-manipulation", "graph", "array", "dynamic-programming", "bitmask"], + }, + "LCP 05": { topicTags: ["binary-indexed-tree", "segment-tree", "array"] }, + "LCP 06": { topicTags: ["array", "math"] }, + "LCP 07": { + topicTags: ["depth-first-search", "breadth-first-search", "graph", "dynamic-programming"], + }, + "LCP 08": { topicTags: ["array", "binary-search", "sorting"] }, + "LCP 09": { + topicTags: ["breadth-first-search", "segment-tree", "array", "dynamic-programming"], + }, + "LCP 10": { + topicTags: ["tree", "depth-first-search", "dynamic-programming", "binary-tree"], + }, + "LCP 11": { + topicTags: ["array", "hash-table", "math", "probability-and-statistics"], + }, + "LCP 12": { topicTags: ["array", "binary-search"] }, + "LCP 13": { + topicTags: ["bit-manipulation", "breadth-first-search", "array", "dynamic-programming", "bitmask", "matrix"], + }, + "LCP 14": { + topicTags: ["array", "math", "dynamic-programming", "number-theory"], + }, + "LCP 15": { topicTags: ["greedy", "geometry", "array", "math"] }, + "LCP 16": { topicTags: ["graph", "geometry", "math"] }, + "LCP 17": { topicTags: ["math", "string", "simulation"] }, + "LCP 18": { + topicTags: ["array", "two-pointers", "binary-search", "sorting"], + }, + "LCP 19": { topicTags: ["string", "dynamic-programming"] }, + "LCP 20": { topicTags: ["memoization", "array", "dynamic-programming"] }, + "LCP 21": { + topicTags: ["depth-first-search", "breadth-first-search", "graph", "topological-sort"], + }, + "LCP 22": { topicTags: ["math"] }, + "LCP 23": { topicTags: ["queue", "array", "simulation"] }, + "LCP 24": { topicTags: ["array", "math", "heap-priority-queue"] }, + "LCP 25": { topicTags: ["math", "dynamic-programming", "combinatorics"] }, + "LCP 26": { topicTags: ["tree", "dynamic-programming", "binary-tree"] }, + "LCP 27": { topicTags: ["design", "segment-tree", "math", "ordered-set"] }, + "LCP 28": { + topicTags: ["array", "two-pointers", "binary-search", "sorting"], + }, + "LCP 29": { topicTags: ["math"] }, + "LCP 30": { topicTags: ["greedy", "array", "heap-priority-queue"] }, + "LCP 31": { + topicTags: ["depth-first-search", "breadth-first-search", "array", "dynamic-programming", "matrix"], + }, + "LCP 32": { topicTags: ["greedy", "array", "heap-priority-queue"] }, + "LCP 33": { topicTags: ["greedy", "array", "heap-priority-queue"] }, + "LCP 34": { topicTags: ["tree", "dynamic-programming", "binary-tree"] }, + "LCP 35": { topicTags: ["graph", "shortest-path", "heap-priority-queue"] }, + "LCP 36": { topicTags: ["array", "dynamic-programming", "sorting"] }, + "LCP 37": { + topicTags: ["greedy", "geometry", "array", "math", "combinatorics", "sorting"], + }, + "LCP 38": { topicTags: ["array", "dynamic-programming", "matrix"] }, + "LCP 39": { topicTags: ["array", "hash-table", "counting", "matrix"] }, + "LCP 40": { topicTags: ["greedy", "array", "sorting"] }, + "LCP 41": { topicTags: ["breadth-first-search", "array", "matrix"] }, + "LCP 42": { + topicTags: ["geometry", "array", "hash-table", "math", "binary-search", "sorting"], + }, + "LCP 43": { topicTags: ["array", "string", "dynamic-programming"] }, + "LCP 44": { + topicTags: ["tree", "depth-first-search", "breadth-first-search", "hash-table", "binary-tree"], + }, + "LCP 45": { + topicTags: [ + "depth-first-search", + "breadth-first-search", + "memoization", + "array", + "dynamic-programming", + "matrix", + ], + }, + "LCP 46": { topicTags: ["graph", "array", "math"] }, + "LCP 47": { topicTags: ["array", "dynamic-programming"] }, + "LCP 48": { topicTags: ["array", "math", "enumeration", "game-theory"] }, + "LCP 49": { + topicTags: ["bit-manipulation", "union-find", "array", "heap-priority-queue"], + }, + "LCP 50": { topicTags: ["array", "simulation"] }, + "LCP 51": { + topicTags: ["bit-manipulation", "array", "backtracking", "enumeration"], + }, + "LCP 52": { + topicTags: ["tree", "segment-tree", "binary-search-tree", "array", "binary-search", "binary-tree", "ordered-set"], + }, + "LCP 53": { + topicTags: ["bit-manipulation", "array", "dynamic-programming", "bitmask"], + }, + "LCP 54": { topicTags: ["graph", "array", "biconnected-component"] }, + "LCP 55": { topicTags: ["array"] }, + "LCP 56": { + topicTags: ["breadth-first-search", "graph", "array", "matrix", "shortest-path", "heap-priority-queue"], + }, + "LCP 57": { + topicTags: ["array", "dynamic-programming", "matrix", "sorting"], + }, + "LCP 58": { topicTags: ["array", "backtracking", "matrix"] }, + "LCP 59": { topicTags: ["array", "dynamic-programming"] }, + "LCP 60": { topicTags: ["tree", "dynamic-programming", "binary-tree"] }, + "LCP 61": { topicTags: [] }, + "LCP 62": { topicTags: [] }, + "LCP 63": { topicTags: [] }, + "LCP 64": { topicTags: [] }, + "LCP 65": { topicTags: [] }, + "LCS 01": { topicTags: ["greedy", "math", "dynamic-programming"] }, + "LCS 02": { topicTags: ["greedy", "array", "hash-table", "sorting"] }, + "LCS 03": { + topicTags: ["depth-first-search", "breadth-first-search", "union-find", "array", "matrix"], + }, + "剑指 Offer 03": { topicTags: ["array", "hash-table", "sorting"] }, + "剑指 Offer 04": { + topicTags: ["array", "binary-search", "divide-and-conquer", "matrix"], + }, + "剑指 Offer 05": { topicTags: ["string"] }, + "剑指 Offer 06": { + topicTags: ["stack", "recursion", "linked-list", "two-pointers"], + }, + "剑指 Offer 07": { + topicTags: ["tree", "array", "hash-table", "divide-and-conquer", "binary-tree"], + }, + "剑指 Offer 09": { topicTags: ["stack", "design", "queue"] }, + "剑指 Offer 10- I": { + topicTags: ["memoization", "math", "dynamic-programming"], + }, + "剑指 Offer 10- II": { + topicTags: ["memoization", "math", "dynamic-programming"], + }, + "剑指 Offer 11": { topicTags: ["array", "binary-search"] }, + "剑指 Offer 12": { topicTags: ["array", "backtracking", "matrix"] }, + "剑指 Offer 14- I": { topicTags: ["math", "dynamic-programming"] }, + "剑指 Offer 14- II": { topicTags: ["math", "dynamic-programming"] }, + "剑指 Offer 15": { topicTags: ["bit-manipulation"] }, + "剑指 Offer 16": { topicTags: ["recursion", "math"] }, + "剑指 Offer 17": { topicTags: ["array", "math"] }, + "剑指 Offer 18": { topicTags: ["linked-list"] }, + "剑指 Offer 19": { + topicTags: ["recursion", "string", "dynamic-programming"], + }, + "剑指 Offer 20": { topicTags: ["string"] }, + "剑指 Offer 21": { topicTags: ["array", "two-pointers", "sorting"] }, + "剑指 Offer 22": { topicTags: ["linked-list", "two-pointers"] }, + "剑指 Offer 24": { topicTags: ["recursion", "linked-list"] }, + "剑指 Offer 25": { topicTags: ["recursion", "linked-list"] }, + "剑指 Offer 26": { + topicTags: ["tree", "depth-first-search", "binary-tree"], + }, + "剑指 Offer 27": { + topicTags: ["tree", "depth-first-search", "breadth-first-search", "binary-tree"], + }, + "剑指 Offer 28": { + topicTags: ["tree", "depth-first-search", "breadth-first-search", "binary-tree"], + }, + "剑指 Offer 29": { topicTags: ["array", "matrix", "simulation"] }, + "剑指 Offer 30": { topicTags: ["stack", "design"] }, + "剑指 Offer 31": { topicTags: ["stack", "array", "simulation"] }, + "剑指 Offer 32 - I": { + topicTags: ["tree", "breadth-first-search", "binary-tree"], + }, + "剑指 Offer 32 - II": { + topicTags: ["tree", "breadth-first-search", "binary-tree"], + }, + "剑指 Offer 32 - III": { + topicTags: ["tree", "breadth-first-search", "binary-tree"], + }, + "剑指 Offer 33": { + topicTags: ["stack", "tree", "binary-search-tree", "recursion", "binary-tree", "monotonic-stack"], + }, + "剑指 Offer 34": { + topicTags: ["tree", "depth-first-search", "backtracking", "binary-tree"], + }, + "剑指 Offer 35": { topicTags: ["hash-table", "linked-list"] }, + "剑指 Offer 36": { + topicTags: [ + "stack", + "tree", + "depth-first-search", + "binary-search-tree", + "linked-list", + "binary-tree", + "doubly-linked-list", + ], + }, + "剑指 Offer 37": { + topicTags: ["tree", "depth-first-search", "breadth-first-search", "design", "string", "binary-tree"], + }, + "剑指 Offer 38": { topicTags: ["string", "backtracking"] }, + "剑指 Offer 39": { + topicTags: ["array", "hash-table", "divide-and-conquer", "counting", "sorting"], + }, + "剑指 Offer 40": { + topicTags: ["array", "divide-and-conquer", "quickselect", "sorting", "heap-priority-queue"], + }, + "剑指 Offer 41": { + topicTags: ["design", "two-pointers", "data-stream", "sorting", "heap-priority-queue"], + }, + "剑指 Offer 42": { + topicTags: ["array", "divide-and-conquer", "dynamic-programming"], + }, + "剑指 Offer 43": { + topicTags: ["recursion", "math", "dynamic-programming"], + }, + "剑指 Offer 44": { topicTags: ["math", "binary-search"] }, + "剑指 Offer 45": { topicTags: ["greedy", "string", "sorting"] }, + "剑指 Offer 46": { topicTags: ["string", "dynamic-programming"] }, + "剑指 Offer 47": { topicTags: ["array", "dynamic-programming", "matrix"] }, + "剑指 Offer 48": { topicTags: ["hash-table", "string", "sliding-window"] }, + "剑指 Offer 49": { + topicTags: ["hash-table", "math", "dynamic-programming", "heap-priority-queue"], + }, + "剑指 Offer 50": { + topicTags: ["queue", "hash-table", "string", "counting"], + }, + "剑指 Offer 51": { + topicTags: [ + "binary-indexed-tree", + "segment-tree", + "array", + "binary-search", + "divide-and-conquer", + "ordered-set", + "merge-sort", + ], + }, + "剑指 Offer 52": { + topicTags: ["hash-table", "linked-list", "two-pointers"], + }, + "剑指 Offer 53 - I": { topicTags: ["array", "binary-search"] }, + "剑指 Offer 53 - II": { + topicTags: ["bit-manipulation", "array", "hash-table", "math", "binary-search"], + }, + "剑指 Offer 54": { + topicTags: ["tree", "depth-first-search", "binary-search-tree", "binary-tree"], + }, + "剑指 Offer 55 - I": { + topicTags: ["tree", "depth-first-search", "breadth-first-search", "binary-tree"], + }, + "剑指 Offer 55 - II": { + topicTags: ["tree", "depth-first-search", "binary-tree"], + }, + "剑指 Offer 56 - I": { topicTags: ["bit-manipulation", "array"] }, + "剑指 Offer 56 - II": { topicTags: ["bit-manipulation", "array"] }, + "剑指 Offer 57": { topicTags: ["array", "two-pointers", "binary-search"] }, + "剑指 Offer 57 - II": { + topicTags: ["math", "two-pointers", "enumeration"], + }, + "剑指 Offer 58 - I": { topicTags: ["two-pointers", "string"] }, + "剑指 Offer 58 - II": { topicTags: ["math", "two-pointers", "string"] }, + "剑指 Offer 59 - I": { + topicTags: ["queue", "sliding-window", "monotonic-queue", "heap-priority-queue"], + }, + "剑指 Offer 60": { + topicTags: ["math", "dynamic-programming", "probability-and-statistics"], + }, + "剑指 Offer 61": { topicTags: ["array", "sorting"] }, + "剑指 Offer 62": { topicTags: ["recursion", "math"] }, + "剑指 Offer 63": { topicTags: ["array", "dynamic-programming"] }, + "剑指 Offer 64": { + topicTags: ["bit-manipulation", "recursion", "brainteaser"], + }, + "剑指 Offer 65": { topicTags: ["bit-manipulation", "math"] }, + "剑指 Offer 66": { topicTags: ["array", "prefix-sum"] }, + "剑指 Offer 67": { topicTags: ["string"] }, + "剑指 Offer 68 - I": { + topicTags: ["tree", "depth-first-search", "binary-search-tree", "binary-tree"], + }, + "剑指 Offer 68 - II": { + topicTags: ["tree", "depth-first-search", "binary-tree"], + }, + "剑指 Offer II 001": { topicTags: ["bit-manipulation", "math"] }, + "剑指 Offer II 002": { + topicTags: ["bit-manipulation", "math", "string", "simulation"], + }, + "剑指 Offer II 003": { + topicTags: ["bit-manipulation", "dynamic-programming"], + }, + "剑指 Offer II 004": { topicTags: ["bit-manipulation", "array"] }, + "剑指 Offer II 005": { topicTags: ["bit-manipulation", "array", "string"] }, + "剑指 Offer II 006": { + topicTags: ["array", "two-pointers", "binary-search"], + }, + "剑指 Offer II 007": { topicTags: ["array", "two-pointers", "sorting"] }, + "剑指 Offer II 008": { + topicTags: ["array", "binary-search", "prefix-sum", "sliding-window"], + }, + "剑指 Offer II 009": { topicTags: ["array", "sliding-window"] }, + "剑指 Offer II 010": { topicTags: ["array", "hash-table", "prefix-sum"] }, + "剑指 Offer II 011": { topicTags: ["array", "hash-table", "prefix-sum"] }, + "剑指 Offer II 012": { topicTags: ["array", "prefix-sum"] }, + "剑指 Offer II 013": { + topicTags: ["design", "array", "matrix", "prefix-sum"], + }, + "剑指 Offer II 014": { + topicTags: ["hash-table", "two-pointers", "string", "sliding-window"], + }, + "剑指 Offer II 015": { + topicTags: ["hash-table", "string", "sliding-window"], + }, + "剑指 Offer II 016": { + topicTags: ["hash-table", "string", "sliding-window"], + }, + "剑指 Offer II 017": { + topicTags: ["hash-table", "string", "sliding-window"], + }, + "剑指 Offer II 018": { topicTags: ["two-pointers", "string"] }, + "剑指 Offer II 019": { topicTags: ["greedy", "two-pointers", "string"] }, + "剑指 Offer II 020": { topicTags: ["string", "dynamic-programming"] }, + "剑指 Offer II 021": { topicTags: ["linked-list", "two-pointers"] }, + "剑指 Offer II 022": { + topicTags: ["hash-table", "linked-list", "two-pointers"], + }, + "剑指 Offer II 023": { + topicTags: ["hash-table", "linked-list", "two-pointers"], + }, + "剑指 Offer II 024": { topicTags: ["recursion", "linked-list"] }, + "剑指 Offer II 025": { topicTags: ["stack", "linked-list", "math"] }, + "剑指 Offer II 026": { + topicTags: ["stack", "recursion", "linked-list", "two-pointers"], + }, + "剑指 Offer II 027": { + topicTags: ["stack", "recursion", "linked-list", "two-pointers"], + }, + "剑指 Offer II 028": { + topicTags: ["depth-first-search", "linked-list", "doubly-linked-list"], + }, + "剑指 Offer II 029": { topicTags: ["linked-list"] }, + "剑指 Offer II 030": { + topicTags: ["design", "array", "hash-table", "math", "randomized"], + }, + "剑指 Offer II 031": { + topicTags: ["design", "hash-table", "linked-list", "doubly-linked-list"], + }, + "剑指 Offer II 032": { topicTags: ["hash-table", "string", "sorting"] }, + "剑指 Offer II 033": { + topicTags: ["array", "hash-table", "string", "sorting"], + }, + "剑指 Offer II 034": { topicTags: ["array", "hash-table", "string"] }, + "剑指 Offer II 035": { topicTags: ["array", "math", "string", "sorting"] }, + "剑指 Offer II 036": { topicTags: ["stack", "array", "math"] }, + "剑指 Offer II 037": { topicTags: ["stack", "array"] }, + "剑指 Offer II 038": { topicTags: ["stack", "array", "monotonic-stack"] }, + "剑指 Offer II 039": { topicTags: ["stack", "array", "monotonic-stack"] }, + "剑指 Offer II 040": { + topicTags: ["stack", "array", "dynamic-programming", "matrix", "monotonic-stack"], + }, + "剑指 Offer II 041": { + topicTags: ["design", "queue", "array", "data-stream"], + }, + "剑指 Offer II 042": { topicTags: ["design", "queue", "data-stream"] }, + "剑指 Offer II 043": { + topicTags: ["tree", "breadth-first-search", "design", "binary-tree"], + }, + "剑指 Offer II 044": { + topicTags: ["tree", "depth-first-search", "breadth-first-search", "binary-tree"], + }, + "剑指 Offer II 045": { + topicTags: ["tree", "depth-first-search", "breadth-first-search", "binary-tree"], + }, + "剑指 Offer II 046": { + topicTags: ["tree", "depth-first-search", "breadth-first-search", "binary-tree"], + }, + "剑指 Offer II 047": { + topicTags: ["tree", "depth-first-search", "binary-tree"], + }, + "剑指 Offer II 048": { + topicTags: ["tree", "depth-first-search", "breadth-first-search", "design", "string", "binary-tree"], + }, + "剑指 Offer II 049": { + topicTags: ["tree", "depth-first-search", "binary-tree"], + }, + "剑指 Offer II 050": { + topicTags: ["tree", "depth-first-search", "binary-tree"], + }, + "剑指 Offer II 051": { + topicTags: ["tree", "depth-first-search", "dynamic-programming", "binary-tree"], + }, + "剑指 Offer II 052": { + topicTags: ["stack", "tree", "depth-first-search", "binary-search-tree", "binary-tree"], + }, + "剑指 Offer II 053": { + topicTags: ["tree", "depth-first-search", "binary-search-tree", "binary-tree"], + }, + "剑指 Offer II 054": { + topicTags: ["tree", "depth-first-search", "binary-search-tree", "binary-tree"], + }, + "剑指 Offer II 055": { + topicTags: ["stack", "tree", "design", "binary-search-tree", "binary-tree", "iterator"], + }, + "剑指 Offer II 056": { + topicTags: [ + "tree", + "depth-first-search", + "breadth-first-search", + "binary-search-tree", + "hash-table", + "two-pointers", + "binary-tree", + ], + }, + "剑指 Offer II 057": { + topicTags: ["array", "bucket-sort", "ordered-set", "sorting", "sliding-window"], + }, + "剑指 Offer II 058": { + topicTags: ["design", "segment-tree", "binary-search", "ordered-set"], + }, + "剑指 Offer II 059": { + topicTags: ["tree", "design", "binary-search-tree", "binary-tree", "data-stream", "heap-priority-queue"], + }, + "剑指 Offer II 060": { + topicTags: [ + "array", + "hash-table", + "divide-and-conquer", + "bucket-sort", + "counting", + "quickselect", + "sorting", + "heap-priority-queue", + ], + }, + "剑指 Offer II 061": { topicTags: ["array", "heap-priority-queue"] }, + "剑指 Offer II 062": { + topicTags: ["design", "trie", "hash-table", "string"], + }, + "剑指 Offer II 063": { + topicTags: ["trie", "array", "hash-table", "string"], + }, + "剑指 Offer II 064": { + topicTags: ["design", "trie", "hash-table", "string"], + }, + "剑指 Offer II 065": { + topicTags: ["trie", "array", "hash-table", "string"], + }, + "剑指 Offer II 066": { + topicTags: ["design", "trie", "hash-table", "string"], + }, + "剑指 Offer II 067": { + topicTags: ["bit-manipulation", "trie", "array", "hash-table"], + }, + "剑指 Offer II 068": { topicTags: ["array", "binary-search"] }, + "剑指 Offer II 069": { topicTags: ["array", "binary-search"] }, + "剑指 Offer II 070": { topicTags: ["array", "binary-search"] }, + "剑指 Offer II 071": { + topicTags: ["math", "binary-search", "prefix-sum", "randomized"], + }, + "剑指 Offer II 072": { topicTags: ["math", "binary-search"] }, + "剑指 Offer II 073": { topicTags: ["array", "binary-search"] }, + "剑指 Offer II 074": { topicTags: ["array", "sorting"] }, + "剑指 Offer II 075": { + topicTags: ["array", "hash-table", "counting-sort", "sorting"], + }, + "剑指 Offer II 076": { + topicTags: ["array", "divide-and-conquer", "quickselect", "sorting", "heap-priority-queue"], + }, + "剑指 Offer II 077": { + topicTags: ["linked-list", "two-pointers", "divide-and-conquer", "sorting", "merge-sort"], + }, + "剑指 Offer II 078": { + topicTags: ["linked-list", "divide-and-conquer", "heap-priority-queue", "merge-sort"], + }, + "剑指 Offer II 079": { + topicTags: ["bit-manipulation", "array", "backtracking"], + }, + "剑指 Offer II 080": { topicTags: ["array", "backtracking"] }, + "剑指 Offer II 081": { topicTags: ["array", "backtracking"] }, + "剑指 Offer II 082": { topicTags: ["array", "backtracking"] }, + "剑指 Offer II 083": { topicTags: ["array", "backtracking"] }, + "剑指 Offer II 084": { topicTags: ["array", "backtracking"] }, + "剑指 Offer II 085": { + topicTags: ["string", "dynamic-programming", "backtracking"], + }, + "剑指 Offer II 086": { + topicTags: ["depth-first-search", "breadth-first-search", "graph", "hash-table"], + }, + "剑指 Offer II 087": { topicTags: ["string", "backtracking"] }, + "剑指 Offer II 088": { topicTags: ["array", "dynamic-programming"] }, + "剑指 Offer II 089": { topicTags: ["array", "dynamic-programming"] }, + "剑指 Offer II 090": { topicTags: ["array", "dynamic-programming"] }, + "剑指 Offer II 091": { topicTags: ["array", "dynamic-programming"] }, + "剑指 Offer II 092": { topicTags: ["string", "dynamic-programming"] }, + "剑指 Offer II 093": { + topicTags: ["array", "hash-table", "dynamic-programming"], + }, + "剑指 Offer II 094": { topicTags: ["string", "dynamic-programming"] }, + "剑指 Offer II 095": { topicTags: ["string", "dynamic-programming"] }, + "剑指 Offer II 096": { topicTags: ["string", "dynamic-programming"] }, + "剑指 Offer II 097": { topicTags: ["string", "dynamic-programming"] }, + "剑指 Offer II 098": { + topicTags: ["math", "dynamic-programming", "combinatorics"], + }, + "剑指 Offer II 099": { + topicTags: ["array", "dynamic-programming", "matrix"], + }, + "剑指 Offer II 100": { topicTags: ["array", "dynamic-programming"] }, + "剑指 Offer II 101": { topicTags: ["math", "string", "simulation"] }, + "剑指 Offer II 102": { + topicTags: ["array", "dynamic-programming", "backtracking"], + }, + "剑指 Offer II 103": { + topicTags: ["breadth-first-search", "array", "dynamic-programming"], + }, + "剑指 Offer II 104": { topicTags: ["array", "dynamic-programming"] }, + "剑指 Offer II 105": { + topicTags: ["depth-first-search", "breadth-first-search", "union-find", "array", "matrix"], + }, + "剑指 Offer II 106": { + topicTags: ["depth-first-search", "breadth-first-search", "union-find", "graph"], + }, + "剑指 Offer II 107": { + topicTags: ["breadth-first-search", "array", "dynamic-programming", "matrix"], + }, + "剑指 Offer II 108": { + topicTags: ["breadth-first-search", "hash-table", "string"], + }, + "剑指 Offer II 109": { + topicTags: ["breadth-first-search", "array", "hash-table", "string"], + }, + "剑指 Offer II 110": { + topicTags: ["depth-first-search", "breadth-first-search", "graph", "backtracking"], + }, + "剑指 Offer II 111": { + topicTags: ["depth-first-search", "breadth-first-search", "union-find", "graph", "array", "shortest-path"], + }, + "剑指 Offer II 112": { + topicTags: [ + "depth-first-search", + "breadth-first-search", + "graph", + "topological-sort", + "memoization", + "array", + "dynamic-programming", + "matrix", + ], + }, + "剑指 Offer II 113": { + topicTags: ["depth-first-search", "breadth-first-search", "graph", "topological-sort"], + }, + "剑指 Offer II 114": { + topicTags: ["depth-first-search", "breadth-first-search", "graph", "topological-sort", "array", "string"], + }, + "剑指 Offer II 115": { topicTags: ["graph", "topological-sort", "array"] }, + "剑指 Offer II 116": { + topicTags: ["depth-first-search", "breadth-first-search", "union-find", "graph"], + }, + "剑指 Offer II 117": { + topicTags: ["depth-first-search", "breadth-first-search", "union-find", "array", "string"], + }, + "剑指 Offer II 118": { + topicTags: ["depth-first-search", "breadth-first-search", "union-find", "graph"], + }, + "剑指 Offer II 119": { topicTags: ["union-find", "array", "hash-table"] }, + "面试题 01.01": { + topicTags: ["bit-manipulation", "hash-table", "string", "sorting"], + }, + "面试题 01.02": { topicTags: ["hash-table", "string", "sorting"] }, + "面试题 01.03": { topicTags: ["string"] }, + "面试题 01.04": { topicTags: ["bit-manipulation", "hash-table", "string"] }, + "面试题 01.05": { topicTags: ["two-pointers", "string"] }, + "面试题 01.06": { topicTags: ["two-pointers", "string"] }, + "面试题 01.07": { topicTags: ["array", "math", "matrix"] }, + "面试题 01.08": { topicTags: ["array", "hash-table", "matrix"] }, + "面试题 01.09": { topicTags: ["string", "string-matching"] }, + "面试题 02.01": { + topicTags: ["hash-table", "linked-list", "two-pointers"], + }, + "面试题 02.02": { topicTags: ["linked-list", "two-pointers"] }, + "面试题 02.03": { topicTags: ["linked-list"] }, + "面试题 02.04": { topicTags: ["linked-list", "two-pointers"] }, + "面试题 02.05": { topicTags: ["recursion", "linked-list", "math"] }, + "面试题 02.06": { + topicTags: ["stack", "recursion", "linked-list", "two-pointers"], + }, + "面试题 02.07": { + topicTags: ["hash-table", "linked-list", "two-pointers"], + }, + "面试题 02.08": { + topicTags: ["hash-table", "linked-list", "two-pointers"], + }, + "面试题 03.01": { topicTags: ["stack", "design", "array"] }, + "面试题 03.02": { topicTags: ["stack", "design"] }, + "面试题 03.03": { topicTags: ["stack", "design", "linked-list"] }, + "面试题 03.04": { topicTags: ["stack", "design", "queue"] }, + "面试题 03.05": { topicTags: ["stack", "design", "monotonic-stack"] }, + "面试题 03.06": { topicTags: ["design", "queue"] }, + "面试题 04.01": { + topicTags: ["depth-first-search", "breadth-first-search", "union-find", "graph"], + }, + "面试题 04.02": { + topicTags: ["tree", "binary-search-tree", "array", "divide-and-conquer", "binary-tree"], + }, + "面试题 04.03": { + topicTags: ["tree", "breadth-first-search", "linked-list", "binary-tree"], + }, + "面试题 04.04": { + topicTags: ["tree", "depth-first-search", "binary-tree"], + }, + "面试题 04.05": { + topicTags: ["tree", "depth-first-search", "binary-search-tree", "binary-tree"], + }, + "面试题 04.06": { + topicTags: ["tree", "depth-first-search", "binary-search-tree", "binary-tree"], + }, + "面试题 04.08": { + topicTags: ["tree", "depth-first-search", "binary-tree"], + }, + "面试题 04.09": { + topicTags: ["tree", "binary-search-tree", "backtracking", "binary-tree"], + }, + "面试题 04.10": { + topicTags: ["tree", "depth-first-search", "binary-tree", "string-matching", "hash-function"], + }, + "面试题 04.12": { + topicTags: ["tree", "depth-first-search", "binary-tree"], + }, + "面试题 05.01": { topicTags: ["bit-manipulation"] }, + "面试题 05.02": { topicTags: ["bit-manipulation", "math", "string"] }, + "面试题 05.03": { topicTags: ["bit-manipulation", "dynamic-programming"] }, + "面试题 05.04": { topicTags: ["bit-manipulation"] }, + "面试题 05.06": { topicTags: ["bit-manipulation"] }, + "面试题 05.07": { topicTags: ["bit-manipulation"] }, + "面试题 05.08": { topicTags: ["bit-manipulation", "array", "math"] }, + "面试题 08.01": { + topicTags: ["memoization", "math", "dynamic-programming"], + }, + "面试题 08.02": { + topicTags: ["array", "dynamic-programming", "backtracking", "matrix"], + }, + "面试题 08.03": { topicTags: ["array", "binary-search"] }, + "面试题 08.04": { + topicTags: ["bit-manipulation", "array", "backtracking"], + }, + "面试题 08.05": { topicTags: ["bit-manipulation", "recursion", "math"] }, + "面试题 08.06": { topicTags: ["recursion", "array"] }, + "面试题 08.07": { topicTags: ["string", "backtracking"] }, + "面试题 08.08": { topicTags: ["string", "backtracking"] }, + "面试题 08.09": { + topicTags: ["string", "dynamic-programming", "backtracking"], + }, + "面试题 08.10": { + topicTags: ["depth-first-search", "breadth-first-search", "array", "matrix"], + }, + "面试题 08.11": { topicTags: ["array", "math", "dynamic-programming"] }, + "面试题 08.12": { topicTags: ["array", "backtracking"] }, + "面试题 08.13": { topicTags: ["array", "dynamic-programming", "sorting"] }, + "面试题 08.14": { + topicTags: ["memoization", "string", "dynamic-programming"], + }, + "面试题 10.01": { topicTags: ["array", "two-pointers", "sorting"] }, + "面试题 10.02": { topicTags: ["array", "hash-table", "string", "sorting"] }, + "面试题 10.03": { topicTags: ["array", "binary-search"] }, + "面试题 10.05": { topicTags: ["array", "string", "binary-search"] }, + "面试题 10.09": { + topicTags: ["array", "binary-search", "divide-and-conquer", "matrix"], + }, + "面试题 10.10": { + topicTags: ["design", "binary-indexed-tree", "binary-search", "data-stream"], + }, + "面试题 10.11": { topicTags: ["greedy", "array", "sorting"] }, + "面试题 16.01": { topicTags: ["bit-manipulation", "math"] }, + "面试题 16.02": { + topicTags: ["design", "trie", "array", "hash-table", "string"], + }, + "面试题 16.03": { topicTags: ["geometry", "math"] }, + "面试题 16.04": { topicTags: ["array", "counting", "matrix"] }, + "面试题 16.05": { topicTags: ["math"] }, + "面试题 16.06": { + topicTags: ["array", "two-pointers", "binary-search", "sorting"], + }, + "面试题 16.07": { topicTags: ["bit-manipulation", "brainteaser", "math"] }, + "面试题 16.08": { topicTags: ["recursion", "math", "string"] }, + "面试题 16.09": { topicTags: ["design", "math"] }, + "面试题 16.10": { topicTags: ["array", "counting"] }, + "面试题 16.11": { topicTags: ["array", "math"] }, + "面试题 16.13": { topicTags: ["geometry", "math"] }, + "面试题 16.14": { topicTags: ["geometry", "array", "hash-table", "math"] }, + "面试题 16.15": { topicTags: ["hash-table", "string", "counting"] }, + "面试题 16.16": { + topicTags: ["stack", "greedy", "array", "two-pointers", "sorting", "monotonic-stack"], + }, + "面试题 16.17": { + topicTags: ["array", "divide-and-conquer", "dynamic-programming"], + }, + "面试题 16.18": { + topicTags: ["math", "string", "backtracking", "enumeration"], + }, + "面试题 16.19": { + topicTags: ["depth-first-search", "breadth-first-search", "union-find", "array", "matrix"], + }, + "面试题 16.20": { topicTags: ["array", "hash-table", "string"] }, + "面试题 16.21": { + topicTags: ["array", "hash-table", "binary-search", "sorting"], + }, + "面试题 16.22": { + topicTags: ["array", "hash-table", "string", "matrix", "simulation"], + }, + "面试题 16.24": { + topicTags: ["array", "hash-table", "two-pointers", "counting", "sorting"], + }, + "面试题 16.25": { + topicTags: ["design", "hash-table", "linked-list", "doubly-linked-list"], + }, + "面试题 16.26": { topicTags: ["stack", "math", "string"] }, + "面试题 17.01": { topicTags: ["bit-manipulation", "math"] }, + "面试题 17.04": { + topicTags: ["bit-manipulation", "array", "hash-table", "math", "sorting"], + }, + "面试题 17.05": { topicTags: ["array", "hash-table", "prefix-sum"] }, + "面试题 17.06": { topicTags: ["recursion", "math", "dynamic-programming"] }, + "面试题 17.07": { + topicTags: [ + "depth-first-search", + "breadth-first-search", + "union-find", + "array", + "hash-table", + "string", + "counting", + ], + }, + "面试题 17.08": { + topicTags: ["array", "binary-search", "dynamic-programming", "sorting"], + }, + "面试题 17.09": { + topicTags: ["hash-table", "math", "dynamic-programming", "heap-priority-queue"], + }, + "面试题 17.10": { topicTags: ["array", "counting"] }, + "面试题 17.11": { topicTags: ["array", "string"] }, + "面试题 17.12": { + topicTags: ["stack", "tree", "depth-first-search", "binary-search-tree", "linked-list", "binary-tree"], + }, + "面试题 17.13": { + topicTags: ["trie", "array", "hash-table", "string", "dynamic-programming", "hash-function", "rolling-hash"], + }, + "面试题 17.14": { + topicTags: ["array", "divide-and-conquer", "quickselect", "sorting", "heap-priority-queue"], + }, + "面试题 17.15": { topicTags: ["trie", "array", "hash-table", "string"] }, + "面试题 17.16": { topicTags: ["array", "dynamic-programming"] }, + "面试题 17.17": { + topicTags: ["trie", "array", "hash-table", "string", "string-matching", "sliding-window"], + }, + "面试题 17.18": { topicTags: ["array", "hash-table", "sliding-window"] }, + "面试题 17.19": { topicTags: ["bit-manipulation", "array", "hash-table"] }, + "面试题 17.20": { + topicTags: ["design", "two-pointers", "data-stream", "sorting", "heap-priority-queue"], + }, + "面试题 17.21": { + topicTags: ["stack", "array", "two-pointers", "dynamic-programming", "monotonic-stack"], + }, + "面试题 17.22": { + topicTags: ["breadth-first-search", "hash-table", "string", "backtracking"], + }, + "面试题 17.23": { topicTags: ["array", "dynamic-programming", "matrix"] }, + "面试题 17.24": { + topicTags: ["array", "dynamic-programming", "matrix", "prefix-sum"], + }, + "面试题 17.25": { topicTags: ["trie", "array", "string", "backtracking"] }, + "面试题 17.26": { topicTags: ["array", "hash-table", "sorting"] }, + 面试题13: { + topicTags: ["depth-first-search", "breadth-first-search", "dynamic-programming"], + }, + "面试题59 - II": { topicTags: ["design", "queue", "monotonic-queue"] }, + }; - private tagsData = { - "1": { "topicTags": ["array", "hash-table"] }, - "2": { "topicTags": ["recursion", "linked-list", "math"] }, - "3": { "topicTags": ["hash-table", "string", "sliding-window"] }, - "4": { "topicTags": ["array", "binary-search", "divide-and-conquer"] }, - "5": { "topicTags": ["string", "dynamic-programming"] }, - "6": { "topicTags": ["string"] }, - "7": { "topicTags": ["math"] }, - "8": { "topicTags": ["string"] }, - "9": { "topicTags": ["math"] }, - "10": { "topicTags": ["recursion", "string", "dynamic-programming"] }, - "11": { "topicTags": ["greedy", "array", "two-pointers"] }, - "12": { "topicTags": ["hash-table", "math", "string"] }, - "13": { "topicTags": ["hash-table", "math", "string"] }, - "14": { "topicTags": ["string"] }, - "15": { "topicTags": ["array", "two-pointers", "sorting"] }, - "16": { "topicTags": ["array", "two-pointers", "sorting"] }, - "17": { "topicTags": ["hash-table", "string", "backtracking"] }, - "18": { "topicTags": ["array", "two-pointers", "sorting"] }, - "19": { "topicTags": ["linked-list", "two-pointers"] }, - "20": { "topicTags": ["stack", "string"] }, - "21": { "topicTags": ["recursion", "linked-list"] }, - "22": { "topicTags": ["string", "dynamic-programming", "backtracking"] }, - "23": { "topicTags": ["linked-list", "divide-and-conquer", "heap-priority-queue", "merge-sort"] }, - "24": { "topicTags": ["recursion", "linked-list"] }, - "25": { "topicTags": ["recursion", "linked-list"] }, - "26": { "topicTags": ["array", "two-pointers"] }, - "27": { "topicTags": ["array", "two-pointers"] }, - "28": { "topicTags": ["two-pointers", "string", "string-matching"] }, - "29": { "topicTags": ["bit-manipulation", "math"] }, - "30": { "topicTags": ["hash-table", "string", "sliding-window"] }, - "31": { "topicTags": ["array", "two-pointers"] }, - "32": { "topicTags": ["stack", "string", "dynamic-programming"] }, - "33": { "topicTags": ["array", "binary-search"] }, - "34": { "topicTags": ["array", "binary-search"] }, - "35": { "topicTags": ["array", "binary-search"] }, - "36": { "topicTags": ["array", "hash-table", "matrix"] }, - "37": { "topicTags": ["array", "backtracking", "matrix"] }, - "38": { "topicTags": ["string"] }, - "39": { "topicTags": ["array", "backtracking"] }, - "40": { "topicTags": ["array", "backtracking"] }, - "41": { "topicTags": ["array", "hash-table"] }, - "42": { "topicTags": ["stack", "array", "two-pointers", "dynamic-programming", "monotonic-stack"] }, - "43": { "topicTags": ["math", "string", "simulation"] }, - "44": { "topicTags": ["greedy", "recursion", "string", "dynamic-programming"] }, - "45": { "topicTags": ["greedy", "array", "dynamic-programming"] }, - "46": { "topicTags": ["array", "backtracking"] }, - "47": { "topicTags": ["array", "backtracking"] }, - "48": { "topicTags": ["array", "math", "matrix"] }, - "49": { "topicTags": ["array", "hash-table", "string", "sorting"] }, - "50": { "topicTags": ["recursion", "math"] }, - "51": { "topicTags": ["array", "backtracking"] }, - "52": { "topicTags": ["backtracking"] }, - "53": { "topicTags": ["array", "divide-and-conquer", "dynamic-programming"] }, - "54": { "topicTags": ["array", "matrix", "simulation"] }, - "55": { "topicTags": ["greedy", "array", "dynamic-programming"] }, - "56": { "topicTags": ["array", "sorting"] }, - "57": { "topicTags": ["array"] }, - "58": { "topicTags": ["string"] }, - "59": { "topicTags": ["array", "matrix", "simulation"] }, - "60": { "topicTags": ["recursion", "math"] }, - "61": { "topicTags": ["linked-list", "two-pointers"] }, - "62": { "topicTags": ["math", "dynamic-programming", "combinatorics"] }, - "63": { "topicTags": ["array", "dynamic-programming", "matrix"] }, - "64": { "topicTags": ["array", "dynamic-programming", "matrix"] }, - "65": { "topicTags": ["string"] }, - "66": { "topicTags": ["array", "math"] }, - "67": { "topicTags": ["bit-manipulation", "math", "string", "simulation"] }, - "68": { "topicTags": ["array", "string", "simulation"] }, - "69": { "topicTags": ["math", "binary-search"] }, - "70": { "topicTags": ["memoization", "math", "dynamic-programming"] }, - "71": { "topicTags": ["stack", "string"] }, - "72": { "topicTags": ["string", "dynamic-programming"] }, - "73": { "topicTags": ["array", "hash-table", "matrix"] }, - "74": { "topicTags": ["array", "binary-search", "matrix"] }, - "75": { "topicTags": ["array", "two-pointers", "sorting"] }, - "76": { "topicTags": ["hash-table", "string", "sliding-window"] }, - "77": { "topicTags": ["backtracking"] }, - "78": { "topicTags": ["bit-manipulation", "array", "backtracking"] }, - "79": { "topicTags": ["array", "backtracking", "matrix"] }, - "80": { "topicTags": ["array", "two-pointers"] }, - "81": { "topicTags": ["array", "binary-search"] }, - "82": { "topicTags": ["linked-list", "two-pointers"] }, - "83": { "topicTags": ["linked-list"] }, - "84": { "topicTags": ["stack", "array", "monotonic-stack"] }, - "85": { "topicTags": ["stack", "array", "dynamic-programming", "matrix", "monotonic-stack"] }, - "86": { "topicTags": ["linked-list", "two-pointers"] }, - "87": { "topicTags": ["string", "dynamic-programming"] }, - "88": { "topicTags": ["array", "two-pointers", "sorting"] }, - "89": { "topicTags": ["bit-manipulation", "math", "backtracking"] }, - "90": { "topicTags": ["bit-manipulation", "array", "backtracking"] }, - "91": { "topicTags": ["string", "dynamic-programming"] }, - "92": { "topicTags": ["linked-list"] }, - "93": { "topicTags": ["string", "backtracking"] }, - "94": { "topicTags": ["stack", "tree", "depth-first-search", "binary-tree"] }, - "95": { "topicTags": ["tree", "binary-search-tree", "dynamic-programming", "backtracking", "binary-tree"] }, - "96": { "topicTags": ["tree", "binary-search-tree", "math", "dynamic-programming", "binary-tree"] }, - "97": { "topicTags": ["string", "dynamic-programming"] }, - "98": { "topicTags": ["tree", "depth-first-search", "binary-search-tree", "binary-tree"] }, - "99": { "topicTags": ["tree", "depth-first-search", "binary-search-tree", "binary-tree"] }, - "100": { "topicTags": ["tree", "depth-first-search", "breadth-first-search", "binary-tree"] }, - "101": { "topicTags": ["tree", "depth-first-search", "breadth-first-search", "binary-tree"] }, - "102": { "topicTags": ["tree", "breadth-first-search", "binary-tree"] }, - "103": { "topicTags": ["tree", "breadth-first-search", "binary-tree"] }, - "104": { "topicTags": ["tree", "depth-first-search", "breadth-first-search", "binary-tree"] }, - "105": { "topicTags": ["tree", "array", "hash-table", "divide-and-conquer", "binary-tree"] }, - "106": { "topicTags": ["tree", "array", "hash-table", "divide-and-conquer", "binary-tree"] }, - "107": { "topicTags": ["tree", "breadth-first-search", "binary-tree"] }, - "108": { "topicTags": ["tree", "binary-search-tree", "array", "divide-and-conquer", "binary-tree"] }, - "109": { "topicTags": ["tree", "binary-search-tree", "linked-list", "divide-and-conquer", "binary-tree"] }, - "110": { "topicTags": ["tree", "depth-first-search", "binary-tree"] }, - "111": { "topicTags": ["tree", "depth-first-search", "breadth-first-search", "binary-tree"] }, - "112": { "topicTags": ["tree", "depth-first-search", "breadth-first-search", "binary-tree"] }, - "113": { "topicTags": ["tree", "depth-first-search", "backtracking", "binary-tree"] }, - "114": { "topicTags": ["stack", "tree", "depth-first-search", "linked-list", "binary-tree"] }, - "115": { "topicTags": ["string", "dynamic-programming"] }, - "116": { "topicTags": ["tree", "depth-first-search", "breadth-first-search", "linked-list", "binary-tree"] }, - "117": { "topicTags": ["tree", "depth-first-search", "breadth-first-search", "linked-list", "binary-tree"] }, - "118": { "topicTags": ["array", "dynamic-programming"] }, - "119": { "topicTags": ["array", "dynamic-programming"] }, - "120": { "topicTags": ["array", "dynamic-programming"] }, - "121": { "topicTags": ["array", "dynamic-programming"] }, - "122": { "topicTags": ["greedy", "array", "dynamic-programming"] }, - "123": { "topicTags": ["array", "dynamic-programming"] }, - "124": { "topicTags": ["tree", "depth-first-search", "dynamic-programming", "binary-tree"] }, - "125": { "topicTags": ["two-pointers", "string"] }, - "126": { "topicTags": ["breadth-first-search", "hash-table", "string", "backtracking"] }, - "127": { "topicTags": ["breadth-first-search", "hash-table", "string"] }, - "128": { "topicTags": ["union-find", "array", "hash-table"] }, - "129": { "topicTags": ["tree", "depth-first-search", "binary-tree"] }, - "130": { "topicTags": ["depth-first-search", "breadth-first-search", "union-find", "array", "matrix"] }, - "131": { "topicTags": ["string", "dynamic-programming", "backtracking"] }, - "132": { "topicTags": ["string", "dynamic-programming"] }, - "133": { "topicTags": ["depth-first-search", "breadth-first-search", "graph", "hash-table"] }, - "134": { "topicTags": ["greedy", "array"] }, - "135": { "topicTags": ["greedy", "array"] }, - "136": { "topicTags": ["bit-manipulation", "array"] }, - "137": { "topicTags": ["bit-manipulation", "array"] }, - "138": { "topicTags": ["hash-table", "linked-list"] }, - "139": { "topicTags": ["trie", "memoization", "hash-table", "string", "dynamic-programming"] }, - "140": { "topicTags": ["trie", "memoization", "hash-table", "string", "dynamic-programming", "backtracking"] }, - "141": { "topicTags": ["hash-table", "linked-list", "two-pointers"] }, - "142": { "topicTags": ["hash-table", "linked-list", "two-pointers"] }, - "143": { "topicTags": ["stack", "recursion", "linked-list", "two-pointers"] }, - "144": { "topicTags": ["stack", "tree", "depth-first-search", "binary-tree"] }, - "145": { "topicTags": ["stack", "tree", "depth-first-search", "binary-tree"] }, - "146": { "topicTags": ["design", "hash-table", "linked-list", "doubly-linked-list"] }, - "147": { "topicTags": ["linked-list", "sorting"] }, - "148": { "topicTags": ["linked-list", "two-pointers", "divide-and-conquer", "sorting", "merge-sort"] }, - "149": { "topicTags": ["geometry", "array", "hash-table", "math"] }, - "150": { "topicTags": ["stack", "array", "math"] }, - "151": { "topicTags": ["two-pointers", "string"] }, - "152": { "topicTags": ["array", "dynamic-programming"] }, - "153": { "topicTags": ["array", "binary-search"] }, - "154": { "topicTags": ["array", "binary-search"] }, - "155": { "topicTags": ["stack", "design"] }, - "156": { "topicTags": ["tree", "depth-first-search", "binary-tree"] }, - "157": { "topicTags": ["string", "interactive", "simulation"] }, - "158": { "topicTags": ["string", "interactive", "simulation"] }, - "159": { "topicTags": ["hash-table", "string", "sliding-window"] }, - "160": { "topicTags": ["hash-table", "linked-list", "two-pointers"] }, - "161": { "topicTags": ["two-pointers", "string"] }, - "162": { "topicTags": ["array", "binary-search"] }, - "163": { "topicTags": ["array"] }, - "164": { "topicTags": ["array", "bucket-sort", "radix-sort", "sorting"] }, - "165": { "topicTags": ["two-pointers", "string"] }, - "166": { "topicTags": ["hash-table", "math", "string"] }, - "167": { "topicTags": ["array", "two-pointers", "binary-search"] }, - "168": { "topicTags": ["math", "string"] }, - "169": { "topicTags": ["array", "hash-table", "divide-and-conquer", "counting", "sorting"] }, - "170": { "topicTags": ["design", "array", "hash-table", "two-pointers", "data-stream"] }, - "171": { "topicTags": ["math", "string"] }, - "172": { "topicTags": ["math"] }, - "173": { "topicTags": ["stack", "tree", "design", "binary-search-tree", "binary-tree", "iterator"] }, - "174": { "topicTags": ["array", "dynamic-programming", "matrix"] }, - "175": { "topicTags": ["database"] }, - "176": { "topicTags": ["database"] }, - "177": { "topicTags": ["database"] }, - "178": { "topicTags": ["database"] }, - "179": { "topicTags": ["greedy", "string", "sorting"] }, - "180": { "topicTags": ["database"] }, - "181": { "topicTags": ["database"] }, - "182": { "topicTags": ["database"] }, - "183": { "topicTags": ["database"] }, - "184": { "topicTags": ["database"] }, - "185": { "topicTags": ["database"] }, - "186": { "topicTags": ["two-pointers", "string"] }, - "187": { "topicTags": ["bit-manipulation", "hash-table", "string", "sliding-window", "hash-function", "rolling-hash"] }, - "188": { "topicTags": ["array", "dynamic-programming"] }, - "189": { "topicTags": ["array", "math", "two-pointers"] }, - "190": { "topicTags": ["bit-manipulation", "divide-and-conquer"] }, - "191": { "topicTags": ["bit-manipulation", "divide-and-conquer"] }, - "192": { "topicTags": ["shell"] }, - "193": { "topicTags": ["shell"] }, - "194": { "topicTags": ["shell"] }, - "195": { "topicTags": ["shell"] }, - "196": { "topicTags": ["database"] }, - "197": { "topicTags": ["database"] }, - "198": { "topicTags": ["array", "dynamic-programming"] }, - "199": { "topicTags": ["tree", "depth-first-search", "breadth-first-search", "binary-tree"] }, - "200": { "topicTags": ["depth-first-search", "breadth-first-search", "union-find", "array", "matrix"] }, - "201": { "topicTags": ["bit-manipulation"] }, - "202": { "topicTags": ["hash-table", "math", "two-pointers"] }, - "203": { "topicTags": ["recursion", "linked-list"] }, - "204": { "topicTags": ["array", "math", "enumeration", "number-theory"] }, - "205": { "topicTags": ["hash-table", "string"] }, - "206": { "topicTags": ["recursion", "linked-list"] }, - "207": { "topicTags": ["depth-first-search", "breadth-first-search", "graph", "topological-sort"] }, - "208": { "topicTags": ["design", "trie", "hash-table", "string"] }, - "209": { "topicTags": ["array", "binary-search", "prefix-sum", "sliding-window"] }, - "210": { "topicTags": ["depth-first-search", "breadth-first-search", "graph", "topological-sort"] }, - "211": { "topicTags": ["depth-first-search", "design", "trie", "string"] }, - "212": { "topicTags": ["trie", "array", "string", "backtracking", "matrix"] }, - "213": { "topicTags": ["array", "dynamic-programming"] }, - "214": { "topicTags": ["string", "string-matching", "hash-function", "rolling-hash"] }, - "215": { "topicTags": ["array", "divide-and-conquer", "quickselect", "sorting", "heap-priority-queue"] }, - "216": { "topicTags": ["array", "backtracking"] }, - "217": { "topicTags": ["array", "hash-table", "sorting"] }, - "218": { "topicTags": ["binary-indexed-tree", "segment-tree", "array", "divide-and-conquer", "ordered-set", "line-sweep", "heap-priority-queue"] }, - "219": { "topicTags": ["array", "hash-table", "sliding-window"] }, - "220": { "topicTags": ["array", "bucket-sort", "ordered-set", "sorting", "sliding-window"] }, - "221": { "topicTags": ["array", "dynamic-programming", "matrix"] }, - "222": { "topicTags": ["tree", "depth-first-search", "binary-search", "binary-tree"] }, - "223": { "topicTags": ["geometry", "math"] }, - "224": { "topicTags": ["stack", "recursion", "math", "string"] }, - "225": { "topicTags": ["stack", "design", "queue"] }, - "226": { "topicTags": ["tree", "depth-first-search", "breadth-first-search", "binary-tree"] }, - "227": { "topicTags": ["stack", "math", "string"] }, - "228": { "topicTags": ["array"] }, - "229": { "topicTags": ["array", "hash-table", "counting", "sorting"] }, - "230": { "topicTags": ["tree", "depth-first-search", "binary-search-tree", "binary-tree"] }, - "231": { "topicTags": ["bit-manipulation", "recursion", "math"] }, - "232": { "topicTags": ["stack", "design", "queue"] }, - "233": { "topicTags": ["recursion", "math", "dynamic-programming"] }, - "234": { "topicTags": ["stack", "recursion", "linked-list", "two-pointers"] }, - "235": { "topicTags": ["tree", "depth-first-search", "binary-search-tree", "binary-tree"] }, - "236": { "topicTags": ["tree", "depth-first-search", "binary-tree"] }, - "237": { "topicTags": ["linked-list"] }, - "238": { "topicTags": ["array", "prefix-sum"] }, - "239": { "topicTags": ["queue", "array", "sliding-window", "monotonic-queue", "heap-priority-queue"] }, - "240": { "topicTags": ["array", "binary-search", "divide-and-conquer", "matrix"] }, - "241": { "topicTags": ["recursion", "memoization", "math", "string", "dynamic-programming"] }, - "242": { "topicTags": ["hash-table", "string", "sorting"] }, - "243": { "topicTags": ["array", "string"] }, - "244": { "topicTags": ["design", "array", "hash-table", "two-pointers", "string"] }, - "245": { "topicTags": ["array", "string"] }, - "246": { "topicTags": ["hash-table", "two-pointers", "string"] }, - "247": { "topicTags": ["recursion", "array", "string"] }, - "248": { "topicTags": ["recursion", "array", "string"] }, - "249": { "topicTags": ["array", "hash-table", "string"] }, - "250": { "topicTags": ["tree", "depth-first-search", "binary-tree"] }, - "251": { "topicTags": ["design", "array", "two-pointers", "iterator"] }, - "252": { "topicTags": ["array", "sorting"] }, - "253": { "topicTags": ["greedy", "array", "two-pointers", "prefix-sum", "sorting", "heap-priority-queue"] }, - "254": { "topicTags": ["array", "backtracking"] }, - "255": { "topicTags": ["stack", "tree", "binary-search-tree", "recursion", "binary-tree", "monotonic-stack"] }, - "256": { "topicTags": ["array", "dynamic-programming"] }, - "257": { "topicTags": ["tree", "depth-first-search", "string", "backtracking", "binary-tree"] }, - "258": { "topicTags": ["math", "number-theory", "simulation"] }, - "259": { "topicTags": ["array", "two-pointers", "binary-search", "sorting"] }, - "260": { "topicTags": ["bit-manipulation", "array"] }, - "261": { "topicTags": ["depth-first-search", "breadth-first-search", "union-find", "graph"] }, - "262": { "topicTags": ["database"] }, - "263": { "topicTags": ["math"] }, - "264": { "topicTags": ["hash-table", "math", "dynamic-programming", "heap-priority-queue"] }, - "265": { "topicTags": ["array", "dynamic-programming"] }, - "266": { "topicTags": ["bit-manipulation", "hash-table", "string"] }, - "267": { "topicTags": ["hash-table", "string", "backtracking"] }, - "268": { "topicTags": ["bit-manipulation", "array", "hash-table", "math", "binary-search", "sorting"] }, - "269": { "topicTags": ["depth-first-search", "breadth-first-search", "graph", "topological-sort", "array", "string"] }, - "270": { "topicTags": ["tree", "depth-first-search", "binary-search-tree", "binary-search", "binary-tree"] }, - "271": { "topicTags": ["design", "array", "string"] }, - "272": { "topicTags": ["stack", "tree", "depth-first-search", "binary-search-tree", "two-pointers", "binary-tree", "heap-priority-queue"] }, - "273": { "topicTags": ["recursion", "math", "string"] }, - "274": { "topicTags": ["array", "counting-sort", "sorting"] }, - "275": { "topicTags": ["array", "binary-search"] }, - "276": { "topicTags": ["dynamic-programming"] }, - "277": { "topicTags": ["greedy", "graph", "two-pointers", "interactive"] }, - "278": { "topicTags": ["binary-search", "interactive"] }, - "279": { "topicTags": ["breadth-first-search", "math", "dynamic-programming"] }, - "280": { "topicTags": ["greedy", "array", "sorting"] }, - "281": { "topicTags": ["design", "queue", "array", "iterator"] }, - "282": { "topicTags": ["math", "string", "backtracking"] }, - "283": { "topicTags": ["array", "two-pointers"] }, - "284": { "topicTags": ["design", "array", "iterator"] }, - "285": { "topicTags": ["tree", "depth-first-search", "binary-search-tree", "binary-tree"] }, - "286": { "topicTags": ["breadth-first-search", "array", "matrix"] }, - "287": { "topicTags": ["bit-manipulation", "array", "two-pointers", "binary-search"] }, - "288": { "topicTags": ["design", "array", "hash-table", "string"] }, - "289": { "topicTags": ["array", "matrix", "simulation"] }, - "290": { "topicTags": ["hash-table", "string"] }, - "291": { "topicTags": ["hash-table", "string", "backtracking"] }, - "292": { "topicTags": ["brainteaser", "math", "game-theory"] }, - "293": { "topicTags": ["string"] }, - "294": { "topicTags": ["memoization", "math", "dynamic-programming", "backtracking", "game-theory"] }, - "295": { "topicTags": ["design", "two-pointers", "data-stream", "sorting", "heap-priority-queue"] }, - "296": { "topicTags": ["array", "math", "matrix", "sorting"] }, - "297": { "topicTags": ["tree", "depth-first-search", "breadth-first-search", "design", "string", "binary-tree"] }, - "298": { "topicTags": ["tree", "depth-first-search", "binary-tree"] }, - "299": { "topicTags": ["hash-table", "string", "counting"] }, - "300": { "topicTags": ["array", "binary-search", "dynamic-programming"] }, - "301": { "topicTags": ["breadth-first-search", "string", "backtracking"] }, - "302": { "topicTags": ["depth-first-search", "breadth-first-search", "array", "binary-search", "matrix"] }, - "303": { "topicTags": ["design", "array", "prefix-sum"] }, - "304": { "topicTags": ["design", "array", "matrix", "prefix-sum"] }, - "305": { "topicTags": ["union-find", "array"] }, - "306": { "topicTags": ["string", "backtracking"] }, - "307": { "topicTags": ["design", "binary-indexed-tree", "segment-tree", "array"] }, - "308": { "topicTags": ["design", "binary-indexed-tree", "segment-tree", "array", "matrix"] }, - "309": { "topicTags": ["array", "dynamic-programming"] }, - "310": { "topicTags": ["depth-first-search", "breadth-first-search", "graph", "topological-sort"] }, - "311": { "topicTags": ["array", "hash-table", "matrix"] }, - "312": { "topicTags": ["array", "dynamic-programming"] }, - "313": { "topicTags": ["array", "math", "dynamic-programming"] }, - "314": { "topicTags": ["tree", "depth-first-search", "breadth-first-search", "hash-table", "binary-tree"] }, - "315": { "topicTags": ["binary-indexed-tree", "segment-tree", "array", "binary-search", "divide-and-conquer", "ordered-set", "merge-sort"] }, - "316": { "topicTags": ["stack", "greedy", "string", "monotonic-stack"] }, - "317": { "topicTags": ["breadth-first-search", "array", "matrix"] }, - "318": { "topicTags": ["bit-manipulation", "array", "string"] }, - "319": { "topicTags": ["brainteaser", "math"] }, - "320": { "topicTags": ["bit-manipulation", "string", "backtracking"] }, - "321": { "topicTags": ["stack", "greedy", "monotonic-stack"] }, - "322": { "topicTags": ["breadth-first-search", "array", "dynamic-programming"] }, - "323": { "topicTags": ["depth-first-search", "breadth-first-search", "union-find", "graph"] }, - "324": { "topicTags": ["array", "divide-and-conquer", "quickselect", "sorting"] }, - "325": { "topicTags": ["array", "hash-table"] }, - "326": { "topicTags": ["recursion", "math"] }, - "327": { "topicTags": ["binary-indexed-tree", "segment-tree", "array", "binary-search", "divide-and-conquer", "ordered-set", "merge-sort"] }, - "328": { "topicTags": ["linked-list"] }, - "329": { "topicTags": ["depth-first-search", "breadth-first-search", "graph", "topological-sort", "memoization", "array", "dynamic-programming", "matrix"] }, - "330": { "topicTags": ["greedy", "array"] }, - "331": { "topicTags": ["stack", "tree", "string", "binary-tree"] }, - "332": { "topicTags": ["depth-first-search", "graph", "eulerian-circuit"] }, - "333": { "topicTags": ["tree", "depth-first-search", "binary-search-tree", "dynamic-programming", "binary-tree"] }, - "334": { "topicTags": ["greedy", "array"] }, - "335": { "topicTags": ["geometry", "array", "math"] }, - "336": { "topicTags": ["trie", "array", "hash-table", "string"] }, - "337": { "topicTags": ["tree", "depth-first-search", "dynamic-programming", "binary-tree"] }, - "338": { "topicTags": ["bit-manipulation", "dynamic-programming"] }, - "339": { "topicTags": ["depth-first-search", "breadth-first-search"] }, - "340": { "topicTags": ["hash-table", "string", "sliding-window"] }, - "341": { "topicTags": ["stack", "tree", "depth-first-search", "design", "queue", "iterator"] }, - "342": { "topicTags": ["bit-manipulation", "recursion", "math"] }, - "343": { "topicTags": ["math", "dynamic-programming"] }, - "344": { "topicTags": ["recursion", "two-pointers", "string"] }, - "345": { "topicTags": ["two-pointers", "string"] }, - "346": { "topicTags": ["design", "queue", "array", "data-stream"] }, - "347": { "topicTags": ["array", "hash-table", "divide-and-conquer", "bucket-sort", "counting", "quickselect", "sorting", "heap-priority-queue"] }, - "348": { "topicTags": ["design", "array", "hash-table", "matrix"] }, - "349": { "topicTags": ["array", "hash-table", "two-pointers", "binary-search", "sorting"] }, - "350": { "topicTags": ["array", "hash-table", "two-pointers", "binary-search", "sorting"] }, - "351": { "topicTags": ["dynamic-programming", "backtracking"] }, - "352": { "topicTags": ["design", "binary-search", "ordered-set"] }, - "353": { "topicTags": ["design", "queue", "array", "matrix"] }, - "354": { "topicTags": ["array", "binary-search", "dynamic-programming", "sorting"] }, - "355": { "topicTags": ["design", "hash-table", "linked-list", "heap-priority-queue"] }, - "356": { "topicTags": ["array", "hash-table", "math"] }, - "357": { "topicTags": ["math", "dynamic-programming", "backtracking"] }, - "358": { "topicTags": ["greedy", "hash-table", "string", "counting", "sorting", "heap-priority-queue"] }, - "359": { "topicTags": ["design", "hash-table"] }, - "360": { "topicTags": ["array", "math", "two-pointers", "sorting"] }, - "361": { "topicTags": ["array", "dynamic-programming", "matrix"] }, - "362": { "topicTags": ["design", "queue", "array", "hash-table", "binary-search"] }, - "363": { "topicTags": ["array", "binary-search", "matrix", "ordered-set", "prefix-sum"] }, - "364": { "topicTags": ["stack", "depth-first-search", "breadth-first-search"] }, - "365": { "topicTags": ["depth-first-search", "breadth-first-search", "math"] }, - "366": { "topicTags": ["tree", "depth-first-search", "binary-tree"] }, - "367": { "topicTags": ["math", "binary-search"] }, - "368": { "topicTags": ["array", "math", "dynamic-programming", "sorting"] }, - "369": { "topicTags": ["linked-list", "math"] }, - "370": { "topicTags": ["array", "prefix-sum"] }, - "371": { "topicTags": ["bit-manipulation", "math"] }, - "372": { "topicTags": ["math", "divide-and-conquer"] }, - "373": { "topicTags": ["array", "heap-priority-queue"] }, - "374": { "topicTags": ["binary-search", "interactive"] }, - "375": { "topicTags": ["math", "dynamic-programming", "game-theory"] }, - "376": { "topicTags": ["greedy", "array", "dynamic-programming"] }, - "377": { "topicTags": ["array", "dynamic-programming"] }, - "378": { "topicTags": ["array", "binary-search", "matrix", "sorting", "heap-priority-queue"] }, - "379": { "topicTags": ["design", "queue", "array", "hash-table", "linked-list"] }, - "380": { "topicTags": ["design", "array", "hash-table", "math", "randomized"] }, - "381": { "topicTags": ["design", "array", "hash-table", "math", "randomized"] }, - "382": { "topicTags": ["reservoir-sampling", "linked-list", "math", "randomized"] }, - "383": { "topicTags": ["hash-table", "string", "counting"] }, - "384": { "topicTags": ["array", "math", "randomized"] }, - "385": { "topicTags": ["stack", "depth-first-search", "string"] }, - "386": { "topicTags": ["depth-first-search", "trie"] }, - "387": { "topicTags": ["queue", "hash-table", "string", "counting"] }, - "388": { "topicTags": ["stack", "depth-first-search", "string"] }, - "389": { "topicTags": ["bit-manipulation", "hash-table", "string", "sorting"] }, - "390": { "topicTags": ["recursion", "math"] }, - "391": { "topicTags": ["array", "line-sweep"] }, - "392": { "topicTags": ["two-pointers", "string", "dynamic-programming"] }, - "393": { "topicTags": ["bit-manipulation", "array"] }, - "394": { "topicTags": ["stack", "recursion", "string"] }, - "395": { "topicTags": ["hash-table", "string", "divide-and-conquer", "sliding-window"] }, - "396": { "topicTags": ["array", "math", "dynamic-programming"] }, - "397": { "topicTags": ["greedy", "bit-manipulation", "memoization", "dynamic-programming"] }, - "398": { "topicTags": ["reservoir-sampling", "hash-table", "math", "randomized"] }, - "399": { "topicTags": ["depth-first-search", "breadth-first-search", "union-find", "graph", "array", "shortest-path"] }, - "400": { "topicTags": ["math", "binary-search"] }, - "401": { "topicTags": ["bit-manipulation", "backtracking"] }, - "402": { "topicTags": ["stack", "greedy", "string", "monotonic-stack"] }, - "403": { "topicTags": ["array", "dynamic-programming"] }, - "404": { "topicTags": ["tree", "depth-first-search", "breadth-first-search", "binary-tree"] }, - "405": { "topicTags": ["bit-manipulation", "math"] }, - "406": { "topicTags": ["greedy", "binary-indexed-tree", "segment-tree", "array", "sorting"] }, - "407": { "topicTags": ["breadth-first-search", "array", "matrix", "heap-priority-queue"] }, - "408": { "topicTags": ["two-pointers", "string"] }, - "409": { "topicTags": ["greedy", "hash-table", "string"] }, - "410": { "topicTags": ["greedy", "array", "binary-search", "dynamic-programming"] }, - "411": { "topicTags": ["bit-manipulation", "string", "backtracking"] }, - "412": { "topicTags": ["math", "string", "simulation"] }, - "413": { "topicTags": ["array", "dynamic-programming"] }, - "414": { "topicTags": ["array", "sorting"] }, - "415": { "topicTags": ["math", "string", "simulation"] }, - "416": { "topicTags": ["array", "dynamic-programming"] }, - "417": { "topicTags": ["depth-first-search", "breadth-first-search", "array", "matrix"] }, - "418": { "topicTags": ["string", "dynamic-programming", "simulation"] }, - "419": { "topicTags": ["depth-first-search", "array", "matrix"] }, - "420": { "topicTags": ["greedy", "string", "heap-priority-queue"] }, - "421": { "topicTags": ["bit-manipulation", "trie", "array", "hash-table"] }, - "422": { "topicTags": ["array", "matrix"] }, - "423": { "topicTags": ["hash-table", "math", "string"] }, - "424": { "topicTags": ["hash-table", "string", "sliding-window"] }, - "425": { "topicTags": ["trie", "array", "string", "backtracking"] }, - "426": { "topicTags": ["stack", "tree", "depth-first-search", "binary-search-tree", "linked-list", "binary-tree", "doubly-linked-list"] }, - "427": { "topicTags": ["tree", "array", "divide-and-conquer", "matrix"] }, - "428": { "topicTags": ["tree", "depth-first-search", "breadth-first-search", "string"] }, - "429": { "topicTags": ["tree", "breadth-first-search"] }, - "430": { "topicTags": ["depth-first-search", "linked-list", "doubly-linked-list"] }, - "431": { "topicTags": ["tree", "depth-first-search", "breadth-first-search", "design", "binary-tree"] }, - "432": { "topicTags": ["design", "hash-table", "linked-list", "doubly-linked-list"] }, - "433": { "topicTags": ["breadth-first-search", "hash-table", "string"] }, - "434": { "topicTags": ["string"] }, - "435": { "topicTags": ["greedy", "array", "dynamic-programming", "sorting"] }, - "436": { "topicTags": ["array", "binary-search", "sorting"] }, - "437": { "topicTags": ["tree", "depth-first-search", "binary-tree"] }, - "438": { "topicTags": ["hash-table", "string", "sliding-window"] }, - "439": { "topicTags": ["stack", "recursion", "string"] }, - "440": { "topicTags": ["trie"] }, - "441": { "topicTags": ["math", "binary-search"] }, - "442": { "topicTags": ["array", "hash-table"] }, - "443": { "topicTags": ["two-pointers", "string"] }, - "444": { "topicTags": ["graph", "topological-sort", "array"] }, - "445": { "topicTags": ["stack", "linked-list", "math"] }, - "446": { "topicTags": ["array", "dynamic-programming"] }, - "447": { "topicTags": ["array", "hash-table", "math"] }, - "448": { "topicTags": ["array", "hash-table"] }, - "449": { "topicTags": ["tree", "depth-first-search", "breadth-first-search", "design", "binary-search-tree", "string", "binary-tree"] }, - "450": { "topicTags": ["tree", "binary-search-tree", "binary-tree"] }, - "451": { "topicTags": ["hash-table", "string", "bucket-sort", "counting", "sorting", "heap-priority-queue"] }, - "452": { "topicTags": ["greedy", "array", "sorting"] }, - "453": { "topicTags": ["array", "math"] }, - "454": { "topicTags": ["array", "hash-table"] }, - "455": { "topicTags": ["greedy", "array", "two-pointers", "sorting"] }, - "456": { "topicTags": ["stack", "array", "binary-search", "ordered-set", "monotonic-stack"] }, - "457": { "topicTags": ["array", "hash-table", "two-pointers"] }, - "458": { "topicTags": ["math", "dynamic-programming", "combinatorics"] }, - "459": { "topicTags": ["string", "string-matching"] }, - "460": { "topicTags": ["design", "hash-table", "linked-list", "doubly-linked-list"] }, - "461": { "topicTags": ["bit-manipulation"] }, - "462": { "topicTags": ["array", "math", "sorting"] }, - "463": { "topicTags": ["depth-first-search", "breadth-first-search", "array", "matrix"] }, - "464": { "topicTags": ["bit-manipulation", "memoization", "math", "dynamic-programming", "bitmask", "game-theory"] }, - "465": { "topicTags": ["bit-manipulation", "array", "dynamic-programming", "backtracking", "bitmask"] }, - "466": { "topicTags": ["string", "dynamic-programming"] }, - "467": { "topicTags": ["string", "dynamic-programming"] }, - "468": { "topicTags": ["string"] }, - "469": { "topicTags": ["geometry", "math"] }, - "470": { "topicTags": ["math", "rejection-sampling", "probability-and-statistics", "randomized"] }, - "471": { "topicTags": ["string", "dynamic-programming"] }, - "472": { "topicTags": ["depth-first-search", "trie", "array", "string", "dynamic-programming"] }, - "473": { "topicTags": ["bit-manipulation", "array", "dynamic-programming", "backtracking", "bitmask"] }, - "474": { "topicTags": ["array", "string", "dynamic-programming"] }, - "475": { "topicTags": ["array", "two-pointers", "binary-search", "sorting"] }, - "476": { "topicTags": ["bit-manipulation"] }, - "477": { "topicTags": ["bit-manipulation", "array", "math"] }, - "478": { "topicTags": ["geometry", "math", "rejection-sampling", "randomized"] }, - "479": { "topicTags": ["math"] }, - "480": { "topicTags": ["array", "hash-table", "sliding-window", "heap-priority-queue"] }, - "481": { "topicTags": ["two-pointers", "string"] }, - "482": { "topicTags": ["string"] }, - "483": { "topicTags": ["math", "binary-search"] }, - "484": { "topicTags": ["stack", "greedy", "array", "string"] }, - "485": { "topicTags": ["array"] }, - "486": { "topicTags": ["recursion", "array", "math", "dynamic-programming", "game-theory"] }, - "487": { "topicTags": ["array", "dynamic-programming", "sliding-window"] }, - "488": { "topicTags": ["breadth-first-search", "memoization", "string", "dynamic-programming"] }, - "489": { "topicTags": ["backtracking", "interactive"] }, - "490": { "topicTags": ["depth-first-search", "breadth-first-search", "graph"] }, - "491": { "topicTags": ["bit-manipulation", "array", "hash-table", "backtracking"] }, - "492": { "topicTags": ["math"] }, - "493": { "topicTags": ["binary-indexed-tree", "segment-tree", "array", "binary-search", "divide-and-conquer", "ordered-set", "merge-sort"] }, - "494": { "topicTags": ["array", "dynamic-programming", "backtracking"] }, - "495": { "topicTags": ["array", "simulation"] }, - "496": { "topicTags": ["stack", "array", "hash-table", "monotonic-stack"] }, - "497": { "topicTags": ["reservoir-sampling", "math", "binary-search", "ordered-set", "prefix-sum", "randomized"] }, - "498": { "topicTags": ["array", "matrix", "simulation"] }, - "499": { "topicTags": ["depth-first-search", "breadth-first-search", "graph", "shortest-path", "heap-priority-queue"] }, - "500": { "topicTags": ["array", "hash-table", "string"] }, - "501": { "topicTags": ["tree", "depth-first-search", "binary-search-tree", "binary-tree"] }, - "502": { "topicTags": ["greedy", "array", "sorting", "heap-priority-queue"] }, - "503": { "topicTags": ["stack", "array", "monotonic-stack"] }, - "504": { "topicTags": ["math"] }, - "505": { "topicTags": ["depth-first-search", "breadth-first-search", "graph", "shortest-path", "heap-priority-queue"] }, - "506": { "topicTags": ["array", "sorting", "heap-priority-queue"] }, - "507": { "topicTags": ["math"] }, - "508": { "topicTags": ["tree", "depth-first-search", "hash-table", "binary-tree"] }, - "509": { "topicTags": ["recursion", "memoization", "math", "dynamic-programming"] }, - "510": { "topicTags": ["tree", "binary-search-tree", "binary-tree"] }, - "511": { "topicTags": ["database"] }, - "512": { "topicTags": ["database"] }, - "513": { "topicTags": ["tree", "depth-first-search", "breadth-first-search", "binary-tree"] }, - "514": { "topicTags": ["depth-first-search", "breadth-first-search", "string", "dynamic-programming"] }, - "515": { "topicTags": ["tree", "depth-first-search", "breadth-first-search", "binary-tree"] }, - "516": { "topicTags": ["string", "dynamic-programming"] }, - "517": { "topicTags": ["greedy", "array"] }, - "518": { "topicTags": ["array", "dynamic-programming"] }, - "519": { "topicTags": ["reservoir-sampling", "hash-table", "math", "randomized"] }, - "520": { "topicTags": ["string"] }, - "521": { "topicTags": ["string"] }, - "522": { "topicTags": ["array", "hash-table", "two-pointers", "string", "sorting"] }, - "523": { "topicTags": ["array", "hash-table", "math", "prefix-sum"] }, - "524": { "topicTags": ["array", "two-pointers", "string", "sorting"] }, - "525": { "topicTags": ["array", "hash-table", "prefix-sum"] }, - "526": { "topicTags": ["bit-manipulation", "array", "dynamic-programming", "backtracking", "bitmask"] }, - "527": { "topicTags": ["greedy", "trie", "array", "string", "sorting"] }, - "528": { "topicTags": ["math", "binary-search", "prefix-sum", "randomized"] }, - "529": { "topicTags": ["depth-first-search", "breadth-first-search", "array", "matrix"] }, - "530": { "topicTags": ["tree", "depth-first-search", "breadth-first-search", "binary-search-tree", "binary-tree"] }, - "531": { "topicTags": ["array", "hash-table", "matrix"] }, - "532": { "topicTags": ["array", "hash-table", "two-pointers", "binary-search", "sorting"] }, - "533": { "topicTags": ["array", "hash-table", "matrix"] }, - "534": { "topicTags": ["database"] }, - "535": { "topicTags": ["design", "hash-table", "string", "hash-function"] }, - "536": { "topicTags": ["tree", "depth-first-search", "string", "binary-tree"] }, - "537": { "topicTags": ["math", "string", "simulation"] }, - "538": { "topicTags": ["tree", "depth-first-search", "binary-search-tree", "binary-tree"] }, - "539": { "topicTags": ["array", "math", "string", "sorting"] }, - "540": { "topicTags": ["array", "binary-search"] }, - "541": { "topicTags": ["two-pointers", "string"] }, - "542": { "topicTags": ["breadth-first-search", "array", "dynamic-programming", "matrix"] }, - "543": { "topicTags": ["tree", "depth-first-search", "binary-tree"] }, - "544": { "topicTags": ["recursion", "string", "simulation"] }, - "545": { "topicTags": ["tree", "depth-first-search", "binary-tree"] }, - "546": { "topicTags": ["memoization", "array", "dynamic-programming"] }, - "547": { "topicTags": ["depth-first-search", "breadth-first-search", "union-find", "graph"] }, - "548": { "topicTags": ["array", "prefix-sum"] }, - "549": { "topicTags": ["tree", "depth-first-search", "binary-tree"] }, - "550": { "topicTags": ["database"] }, - "551": { "topicTags": ["string"] }, - "552": { "topicTags": ["dynamic-programming"] }, - "553": { "topicTags": ["array", "math", "dynamic-programming"] }, - "554": { "topicTags": ["array", "hash-table"] }, - "555": { "topicTags": ["greedy", "array", "string"] }, - "556": { "topicTags": ["math", "two-pointers", "string"] }, - "557": { "topicTags": ["two-pointers", "string"] }, - "558": { "topicTags": ["tree", "divide-and-conquer"] }, - "559": { "topicTags": ["tree", "depth-first-search", "breadth-first-search"] }, - "560": { "topicTags": ["array", "hash-table", "prefix-sum"] }, - "561": { "topicTags": ["greedy", "array", "counting-sort", "sorting"] }, - "562": { "topicTags": ["array", "dynamic-programming", "matrix"] }, - "563": { "topicTags": ["tree", "depth-first-search", "binary-tree"] }, - "564": { "topicTags": ["math", "string"] }, - "565": { "topicTags": ["depth-first-search", "array"] }, - "566": { "topicTags": ["array", "matrix", "simulation"] }, - "567": { "topicTags": ["hash-table", "two-pointers", "string", "sliding-window"] }, - "568": { "topicTags": ["array", "dynamic-programming", "matrix"] }, - "569": { "topicTags": ["database"] }, - "570": { "topicTags": ["database"] }, - "571": { "topicTags": ["database"] }, - "572": { "topicTags": ["tree", "depth-first-search", "binary-tree", "string-matching", "hash-function"] }, - "573": { "topicTags": ["array", "math"] }, - "574": { "topicTags": ["database"] }, - "575": { "topicTags": ["array", "hash-table"] }, - "576": { "topicTags": ["dynamic-programming"] }, - "577": { "topicTags": ["database"] }, - "578": { "topicTags": ["database"] }, - "579": { "topicTags": ["database"] }, - "580": { "topicTags": ["database"] }, - "581": { "topicTags": ["stack", "greedy", "array", "two-pointers", "sorting", "monotonic-stack"] }, - "582": { "topicTags": ["tree", "depth-first-search", "breadth-first-search", "array", "hash-table"] }, - "583": { "topicTags": ["string", "dynamic-programming"] }, - "584": { "topicTags": ["database"] }, - "585": { "topicTags": ["database"] }, - "586": { "topicTags": ["database"] }, - "587": { "topicTags": ["geometry", "array", "math"] }, - "588": { "topicTags": ["design", "trie", "hash-table", "string"] }, - "589": { "topicTags": ["stack", "tree", "depth-first-search"] }, - "590": { "topicTags": ["stack", "tree", "depth-first-search"] }, - "591": { "topicTags": ["stack", "string"] }, - "592": { "topicTags": ["math", "string", "simulation"] }, - "593": { "topicTags": ["geometry", "math"] }, - "594": { "topicTags": ["array", "hash-table", "sorting"] }, - "595": { "topicTags": ["database"] }, - "596": { "topicTags": ["database"] }, - "597": { "topicTags": ["database"] }, - "598": { "topicTags": ["array", "math"] }, - "599": { "topicTags": ["array", "hash-table", "string"] }, - "600": { "topicTags": ["dynamic-programming"] }, - "601": { "topicTags": ["database"] }, - "602": { "topicTags": ["database"] }, - "603": { "topicTags": ["database"] }, - "604": { "topicTags": ["design", "array", "hash-table", "string", "iterator"] }, - "605": { "topicTags": ["greedy", "array"] }, - "606": { "topicTags": ["tree", "depth-first-search", "string", "binary-tree"] }, - "607": { "topicTags": ["database"] }, - "608": { "topicTags": ["database"] }, - "609": { "topicTags": ["array", "hash-table", "string"] }, - "610": { "topicTags": ["database"] }, - "611": { "topicTags": ["greedy", "array", "two-pointers", "binary-search", "sorting"] }, - "612": { "topicTags": ["database"] }, - "613": { "topicTags": ["database"] }, - "614": { "topicTags": ["database"] }, - "615": { "topicTags": ["database"] }, - "616": { "topicTags": ["trie", "array", "hash-table", "string", "string-matching"] }, - "617": { "topicTags": ["tree", "depth-first-search", "breadth-first-search", "binary-tree"] }, - "618": { "topicTags": ["database"] }, - "619": { "topicTags": ["database"] }, - "620": { "topicTags": ["database"] }, - "621": { "topicTags": ["greedy", "array", "hash-table", "counting", "sorting", "heap-priority-queue"] }, - "622": { "topicTags": ["design", "queue", "array", "linked-list"] }, - "623": { "topicTags": ["tree", "depth-first-search", "breadth-first-search", "binary-tree"] }, - "624": { "topicTags": ["greedy", "array"] }, - "625": { "topicTags": ["greedy", "math"] }, - "626": { "topicTags": ["database"] }, - "627": { "topicTags": ["database"] }, - "628": { "topicTags": ["array", "math", "sorting"] }, - "629": { "topicTags": ["dynamic-programming"] }, - "630": { "topicTags": ["greedy", "array", "heap-priority-queue"] }, - "631": { "topicTags": ["graph", "design", "topological-sort"] }, - "632": { "topicTags": ["greedy", "array", "hash-table", "sorting", "sliding-window", "heap-priority-queue"] }, - "633": { "topicTags": ["math", "two-pointers", "binary-search"] }, - "634": { "topicTags": ["math", "dynamic-programming"] }, - "635": { "topicTags": ["design", "hash-table", "string", "ordered-set"] }, - "636": { "topicTags": ["stack", "array"] }, - "637": { "topicTags": ["tree", "depth-first-search", "breadth-first-search", "binary-tree"] }, - "638": { "topicTags": ["bit-manipulation", "memoization", "array", "dynamic-programming", "backtracking", "bitmask"] }, - "639": { "topicTags": ["string", "dynamic-programming"] }, - "640": { "topicTags": ["math", "string", "simulation"] }, - "641": { "topicTags": ["design", "queue", "array", "linked-list"] }, - "642": { "topicTags": ["design", "trie", "string", "data-stream"] }, - "643": { "topicTags": ["array", "sliding-window"] }, - "644": { "topicTags": ["array", "binary-search", "prefix-sum"] }, - "645": { "topicTags": ["bit-manipulation", "array", "hash-table", "sorting"] }, - "646": { "topicTags": ["greedy", "array", "dynamic-programming", "sorting"] }, - "647": { "topicTags": ["string", "dynamic-programming"] }, - "648": { "topicTags": ["trie", "array", "hash-table", "string"] }, - "649": { "topicTags": ["greedy", "queue", "string"] }, - "650": { "topicTags": ["math", "dynamic-programming"] }, - "651": { "topicTags": ["math", "dynamic-programming"] }, - "652": { "topicTags": ["tree", "depth-first-search", "hash-table", "binary-tree"] }, - "653": { "topicTags": ["tree", "depth-first-search", "breadth-first-search", "binary-search-tree", "hash-table", "two-pointers", "binary-tree"] }, - "654": { "topicTags": ["stack", "tree", "array", "divide-and-conquer", "binary-tree", "monotonic-stack"] }, - "655": { "topicTags": ["tree", "depth-first-search", "breadth-first-search", "binary-tree"] }, - "656": { "topicTags": ["array", "dynamic-programming"] }, - "657": { "topicTags": ["string", "simulation"] }, - "658": { "topicTags": ["array", "two-pointers", "binary-search", "sorting", "heap-priority-queue"] }, - "659": { "topicTags": ["greedy", "array", "hash-table", "heap-priority-queue"] }, - "660": { "topicTags": ["math"] }, - "661": { "topicTags": ["array", "matrix"] }, - "662": { "topicTags": ["tree", "depth-first-search", "breadth-first-search", "binary-tree"] }, - "663": { "topicTags": ["tree", "depth-first-search", "binary-tree"] }, - "664": { "topicTags": ["string", "dynamic-programming"] }, - "665": { "topicTags": ["array"] }, - "666": { "topicTags": ["tree", "depth-first-search", "array", "binary-tree"] }, - "667": { "topicTags": ["array", "math"] }, - "668": { "topicTags": ["math", "binary-search"] }, - "669": { "topicTags": ["tree", "depth-first-search", "binary-search-tree", "binary-tree"] }, - "670": { "topicTags": ["greedy", "math"] }, - "671": { "topicTags": ["tree", "depth-first-search", "binary-tree"] }, - "672": { "topicTags": ["bit-manipulation", "depth-first-search", "breadth-first-search", "math"] }, - "673": { "topicTags": ["binary-indexed-tree", "segment-tree", "array", "dynamic-programming"] }, - "674": { "topicTags": ["array"] }, - "675": { "topicTags": ["breadth-first-search", "array", "matrix", "heap-priority-queue"] }, - "676": { "topicTags": ["design", "trie", "hash-table", "string"] }, - "677": { "topicTags": ["design", "trie", "hash-table", "string"] }, - "678": { "topicTags": ["stack", "greedy", "string", "dynamic-programming"] }, - "679": { "topicTags": ["array", "math", "backtracking"] }, - "680": { "topicTags": ["greedy", "two-pointers", "string"] }, - "681": { "topicTags": ["string", "enumeration"] }, - "682": { "topicTags": ["stack", "array", "simulation"] }, - "683": { "topicTags": ["binary-indexed-tree", "array", "ordered-set", "sliding-window"] }, - "684": { "topicTags": ["depth-first-search", "breadth-first-search", "union-find", "graph"] }, - "685": { "topicTags": ["depth-first-search", "breadth-first-search", "union-find", "graph"] }, - "686": { "topicTags": ["string", "string-matching"] }, - "687": { "topicTags": ["tree", "depth-first-search", "binary-tree"] }, - "688": { "topicTags": ["dynamic-programming"] }, - "689": { "topicTags": ["array", "dynamic-programming"] }, - "690": { "topicTags": ["depth-first-search", "breadth-first-search", "hash-table"] }, - "691": { "topicTags": ["bit-manipulation", "array", "string", "dynamic-programming", "backtracking", "bitmask"] }, - "692": { "topicTags": ["trie", "hash-table", "string", "bucket-sort", "counting", "sorting", "heap-priority-queue"] }, - "693": { "topicTags": ["bit-manipulation"] }, - "694": { "topicTags": ["depth-first-search", "breadth-first-search", "union-find", "hash-table", "hash-function"] }, - "695": { "topicTags": ["depth-first-search", "breadth-first-search", "union-find", "array", "matrix"] }, - "696": { "topicTags": ["two-pointers", "string"] }, - "697": { "topicTags": ["array", "hash-table"] }, - "698": { "topicTags": ["bit-manipulation", "memoization", "array", "dynamic-programming", "backtracking", "bitmask"] }, - "699": { "topicTags": ["segment-tree", "array", "ordered-set"] }, - "700": { "topicTags": ["tree", "binary-search-tree", "binary-tree"] }, - "701": { "topicTags": ["tree", "binary-search-tree", "binary-tree"] }, - "702": { "topicTags": ["array", "binary-search", "interactive"] }, - "703": { "topicTags": ["tree", "design", "binary-search-tree", "binary-tree", "data-stream", "heap-priority-queue"] }, - "704": { "topicTags": ["array", "binary-search"] }, - "705": { "topicTags": ["design", "array", "hash-table", "linked-list", "hash-function"] }, - "706": { "topicTags": ["design", "array", "hash-table", "linked-list", "hash-function"] }, - "707": { "topicTags": ["design", "linked-list"] }, - "708": { "topicTags": ["linked-list"] }, - "709": { "topicTags": ["string"] }, - "710": { "topicTags": ["hash-table", "math", "binary-search", "sorting", "randomized"] }, - "711": { "topicTags": ["depth-first-search", "breadth-first-search", "union-find", "hash-table", "hash-function"] }, - "712": { "topicTags": ["string", "dynamic-programming"] }, - "713": { "topicTags": ["array", "sliding-window"] }, - "714": { "topicTags": ["greedy", "array", "dynamic-programming"] }, - "715": { "topicTags": ["design", "segment-tree", "ordered-set"] }, - "716": { "topicTags": ["stack", "design", "linked-list", "doubly-linked-list", "ordered-set"] }, - "717": { "topicTags": ["array"] }, - "718": { "topicTags": ["array", "binary-search", "dynamic-programming", "sliding-window", "hash-function", "rolling-hash"] }, - "719": { "topicTags": ["array", "two-pointers", "binary-search", "sorting"] }, - "720": { "topicTags": ["trie", "array", "hash-table", "string", "sorting"] }, - "721": { "topicTags": ["depth-first-search", "breadth-first-search", "union-find", "array", "string"] }, - "722": { "topicTags": ["array", "string"] }, - "723": { "topicTags": ["array", "two-pointers", "matrix", "simulation"] }, - "724": { "topicTags": ["array", "prefix-sum"] }, - "725": { "topicTags": ["linked-list"] }, - "726": { "topicTags": ["stack", "hash-table", "string", "sorting"] }, - "727": { "topicTags": ["string", "dynamic-programming", "sliding-window"] }, - "728": { "topicTags": ["math"] }, - "729": { "topicTags": ["design", "segment-tree", "binary-search", "ordered-set"] }, - "730": { "topicTags": ["string", "dynamic-programming"] }, - "731": { "topicTags": ["design", "segment-tree", "binary-search", "ordered-set"] }, - "732": { "topicTags": ["design", "segment-tree", "binary-search", "ordered-set"] }, - "733": { "topicTags": ["depth-first-search", "breadth-first-search", "array", "matrix"] }, - "734": { "topicTags": ["array", "hash-table", "string"] }, - "735": { "topicTags": ["stack", "array"] }, - "736": { "topicTags": ["stack", "recursion", "hash-table", "string"] }, - "737": { "topicTags": ["depth-first-search", "breadth-first-search", "union-find", "array", "hash-table", "string"] }, - "738": { "topicTags": ["greedy", "math"] }, - "739": { "topicTags": ["stack", "array", "monotonic-stack"] }, - "740": { "topicTags": ["array", "hash-table", "dynamic-programming"] }, - "741": { "topicTags": ["array", "dynamic-programming", "matrix"] }, - "742": { "topicTags": ["tree", "depth-first-search", "breadth-first-search", "binary-tree"] }, - "743": { "topicTags": ["depth-first-search", "breadth-first-search", "graph", "shortest-path", "heap-priority-queue"] }, - "744": { "topicTags": ["array", "binary-search"] }, - "745": { "topicTags": ["design", "trie", "hash-table", "string"] }, - "746": { "topicTags": ["array", "dynamic-programming"] }, - "747": { "topicTags": ["array", "sorting"] }, - "748": { "topicTags": ["array", "hash-table", "string"] }, - "749": { "topicTags": ["depth-first-search", "breadth-first-search", "array", "matrix", "simulation"] }, - "750": { "topicTags": ["array", "math", "dynamic-programming", "matrix"] }, - "751": { "topicTags": ["bit-manipulation", "string"] }, - "752": { "topicTags": ["breadth-first-search", "array", "hash-table", "string"] }, - "753": { "topicTags": ["depth-first-search", "graph", "eulerian-circuit"] }, - "754": { "topicTags": ["math", "binary-search"] }, - "755": { "topicTags": ["array", "simulation"] }, - "756": { "topicTags": ["bit-manipulation", "depth-first-search", "breadth-first-search"] }, - "757": { "topicTags": ["greedy", "array", "sorting"] }, - "758": { "topicTags": ["trie", "array", "hash-table", "string", "string-matching"] }, - "759": { "topicTags": ["array", "sorting", "heap-priority-queue"] }, - "760": { "topicTags": ["array", "hash-table"] }, - "761": { "topicTags": ["recursion", "string"] }, - "762": { "topicTags": ["bit-manipulation", "math"] }, - "763": { "topicTags": ["greedy", "hash-table", "two-pointers", "string"] }, - "764": { "topicTags": ["array", "dynamic-programming"] }, - "765": { "topicTags": ["greedy", "depth-first-search", "breadth-first-search", "union-find", "graph"] }, - "766": { "topicTags": ["array", "matrix"] }, - "767": { "topicTags": ["greedy", "hash-table", "string", "counting", "sorting", "heap-priority-queue"] }, - "768": { "topicTags": ["stack", "greedy", "array", "sorting", "monotonic-stack"] }, - "769": { "topicTags": ["stack", "greedy", "array", "sorting", "monotonic-stack"] }, - "770": { "topicTags": ["stack", "recursion", "hash-table", "math", "string"] }, - "771": { "topicTags": ["hash-table", "string"] }, - "772": { "topicTags": ["stack", "recursion", "math", "string"] }, - "773": { "topicTags": ["breadth-first-search", "array", "matrix"] }, - "774": { "topicTags": ["array", "binary-search"] }, - "775": { "topicTags": ["array", "math"] }, - "776": { "topicTags": ["tree", "binary-search-tree", "recursion", "binary-tree"] }, - "777": { "topicTags": ["two-pointers", "string"] }, - "778": { "topicTags": ["depth-first-search", "breadth-first-search", "union-find", "array", "binary-search", "matrix", "heap-priority-queue"] }, - "779": { "topicTags": ["bit-manipulation", "recursion", "math"] }, - "780": { "topicTags": ["math"] }, - "781": { "topicTags": ["greedy", "array", "hash-table", "math"] }, - "782": { "topicTags": ["bit-manipulation", "array", "math", "matrix"] }, - "783": { "topicTags": ["tree", "depth-first-search", "breadth-first-search", "binary-search-tree", "binary-tree"] }, - "784": { "topicTags": ["bit-manipulation", "string", "backtracking"] }, - "785": { "topicTags": ["depth-first-search", "breadth-first-search", "union-find", "graph"] }, - "786": { "topicTags": ["array", "binary-search", "sorting", "heap-priority-queue"] }, - "787": { "topicTags": ["depth-first-search", "breadth-first-search", "graph", "dynamic-programming", "shortest-path", "heap-priority-queue"] }, - "788": { "topicTags": ["math", "dynamic-programming"] }, - "789": { "topicTags": ["array", "math"] }, - "790": { "topicTags": ["dynamic-programming"] }, - "791": { "topicTags": ["hash-table", "string", "sorting"] }, - "792": { "topicTags": ["trie", "hash-table", "string", "sorting"] }, - "793": { "topicTags": ["math", "binary-search"] }, - "794": { "topicTags": ["array", "string"] }, - "795": { "topicTags": ["array", "two-pointers"] }, - "796": { "topicTags": ["string", "string-matching"] }, - "797": { "topicTags": ["depth-first-search", "breadth-first-search", "graph", "backtracking"] }, - "798": { "topicTags": ["array", "prefix-sum"] }, - "799": { "topicTags": ["dynamic-programming"] }, - "800": { "topicTags": ["math", "string", "enumeration"] }, - "801": { "topicTags": ["array", "dynamic-programming"] }, - "802": { "topicTags": ["depth-first-search", "breadth-first-search", "graph", "topological-sort"] }, - "803": { "topicTags": ["union-find", "array", "matrix"] }, - "804": { "topicTags": ["array", "hash-table", "string"] }, - "805": { "topicTags": ["bit-manipulation", "array", "math", "dynamic-programming", "bitmask"] }, - "806": { "topicTags": ["array", "string"] }, - "807": { "topicTags": ["greedy", "array", "matrix"] }, - "808": { "topicTags": ["math", "dynamic-programming", "probability-and-statistics"] }, - "809": { "topicTags": ["array", "two-pointers", "string"] }, - "810": { "topicTags": ["bit-manipulation", "brainteaser", "array", "math", "game-theory"] }, - "811": { "topicTags": ["array", "hash-table", "string", "counting"] }, - "812": { "topicTags": ["geometry", "array", "math"] }, - "813": { "topicTags": ["array", "dynamic-programming"] }, - "814": { "topicTags": ["tree", "depth-first-search", "binary-tree"] }, - "815": { "topicTags": ["breadth-first-search", "array", "hash-table"] }, - "816": { "topicTags": ["string", "backtracking"] }, - "817": { "topicTags": ["array", "hash-table", "linked-list"] }, - "818": { "topicTags": ["dynamic-programming"] }, - "819": { "topicTags": ["hash-table", "string", "counting"] }, - "820": { "topicTags": ["trie", "array", "hash-table", "string"] }, - "821": { "topicTags": ["array", "two-pointers", "string"] }, - "822": { "topicTags": ["array", "hash-table"] }, - "823": { "topicTags": ["array", "hash-table", "dynamic-programming"] }, - "824": { "topicTags": ["string"] }, - "825": { "topicTags": ["array", "two-pointers", "binary-search", "sorting"] }, - "826": { "topicTags": ["greedy", "array", "two-pointers", "binary-search", "sorting"] }, - "827": { "topicTags": ["depth-first-search", "breadth-first-search", "union-find", "array", "matrix"] }, - "828": { "topicTags": ["hash-table", "string", "dynamic-programming"] }, - "829": { "topicTags": ["math", "enumeration"] }, - "830": { "topicTags": ["string"] }, - "831": { "topicTags": ["string"] }, - "832": { "topicTags": ["array", "two-pointers", "matrix", "simulation"] }, - "833": { "topicTags": ["array", "string", "sorting"] }, - "834": { "topicTags": ["tree", "depth-first-search", "graph", "dynamic-programming"] }, - "835": { "topicTags": ["array", "matrix"] }, - "836": { "topicTags": ["geometry", "math"] }, - "837": { "topicTags": ["math", "dynamic-programming", "sliding-window", "probability-and-statistics"] }, - "838": { "topicTags": ["two-pointers", "string", "dynamic-programming"] }, - "839": { "topicTags": ["depth-first-search", "breadth-first-search", "union-find", "array", "string"] }, - "840": { "topicTags": ["array", "math", "matrix"] }, - "841": { "topicTags": ["depth-first-search", "breadth-first-search", "graph"] }, - "842": { "topicTags": ["string", "backtracking"] }, - "843": { "topicTags": ["array", "math", "string", "game-theory", "interactive"] }, - "844": { "topicTags": ["stack", "two-pointers", "string", "simulation"] }, - "845": { "topicTags": ["array", "two-pointers", "dynamic-programming", "enumeration"] }, - "846": { "topicTags": ["greedy", "array", "hash-table", "sorting"] }, - "847": { "topicTags": ["bit-manipulation", "breadth-first-search", "graph", "dynamic-programming", "bitmask"] }, - "848": { "topicTags": ["array", "string"] }, - "849": { "topicTags": ["array"] }, - "850": { "topicTags": ["segment-tree", "array", "ordered-set", "line-sweep"] }, - "851": { "topicTags": ["depth-first-search", "graph", "topological-sort", "array"] }, - "852": { "topicTags": ["array", "binary-search"] }, - "853": { "topicTags": ["stack", "array", "sorting", "monotonic-stack"] }, - "854": { "topicTags": ["breadth-first-search", "string"] }, - "855": { "topicTags": ["design", "ordered-set"] }, - "856": { "topicTags": ["stack", "string"] }, - "857": { "topicTags": ["greedy", "array", "sorting", "heap-priority-queue"] }, - "858": { "topicTags": ["geometry", "math"] }, - "859": { "topicTags": ["hash-table", "string"] }, - "860": { "topicTags": ["greedy", "array"] }, - "861": { "topicTags": ["greedy", "bit-manipulation", "array", "matrix"] }, - "862": { "topicTags": ["queue", "array", "binary-search", "prefix-sum", "sliding-window", "monotonic-queue", "heap-priority-queue"] }, - "863": { "topicTags": ["tree", "depth-first-search", "breadth-first-search", "binary-tree"] }, - "864": { "topicTags": ["bit-manipulation", "breadth-first-search"] }, - "865": { "topicTags": ["tree", "depth-first-search", "breadth-first-search", "hash-table", "binary-tree"] }, - "866": { "topicTags": ["math"] }, - "867": { "topicTags": ["array", "matrix", "simulation"] }, - "868": { "topicTags": ["bit-manipulation"] }, - "869": { "topicTags": ["math", "counting", "enumeration", "sorting"] }, - "870": { "topicTags": ["greedy", "array", "two-pointers", "sorting"] }, - "871": { "topicTags": ["greedy", "array", "dynamic-programming", "heap-priority-queue"] }, - "872": { "topicTags": ["tree", "depth-first-search", "binary-tree"] }, - "873": { "topicTags": ["array", "hash-table", "dynamic-programming"] }, - "874": { "topicTags": ["array", "simulation"] }, - "875": { "topicTags": ["array", "binary-search"] }, - "876": { "topicTags": ["linked-list", "two-pointers"] }, - "877": { "topicTags": ["array", "math", "dynamic-programming", "game-theory"] }, - "878": { "topicTags": ["math", "binary-search"] }, - "879": { "topicTags": ["array", "dynamic-programming"] }, - "880": { "topicTags": ["stack", "string"] }, - "881": { "topicTags": ["greedy", "array", "two-pointers", "sorting"] }, - "882": { "topicTags": ["graph", "shortest-path", "heap-priority-queue"] }, - "883": { "topicTags": ["geometry", "array", "math", "matrix"] }, - "884": { "topicTags": ["hash-table", "string"] }, - "885": { "topicTags": ["array", "matrix", "simulation"] }, - "886": { "topicTags": ["depth-first-search", "breadth-first-search", "union-find", "graph"] }, - "887": { "topicTags": ["math", "binary-search", "dynamic-programming"] }, - "888": { "topicTags": ["array", "hash-table", "binary-search", "sorting"] }, - "889": { "topicTags": ["tree", "array", "hash-table", "divide-and-conquer", "binary-tree"] }, - "890": { "topicTags": ["array", "hash-table", "string"] }, - "891": { "topicTags": ["array", "math", "sorting"] }, - "892": { "topicTags": ["geometry", "array", "math", "matrix"] }, - "893": { "topicTags": ["array", "hash-table", "string"] }, - "894": { "topicTags": ["tree", "recursion", "memoization", "dynamic-programming", "binary-tree"] }, - "895": { "topicTags": ["stack", "design", "hash-table", "ordered-set"] }, - "896": { "topicTags": ["array"] }, - "897": { "topicTags": ["stack", "tree", "depth-first-search", "binary-search-tree", "binary-tree"] }, - "898": { "topicTags": ["bit-manipulation", "array", "dynamic-programming"] }, - "899": { "topicTags": ["math", "string", "sorting"] }, - "900": { "topicTags": ["design", "array", "counting", "iterator"] }, - "901": { "topicTags": ["stack", "design", "data-stream", "monotonic-stack"] }, - "902": { "topicTags": ["array", "math", "string", "binary-search", "dynamic-programming"] }, - "903": { "topicTags": ["dynamic-programming"] }, - "904": { "topicTags": ["array", "hash-table", "sliding-window"] }, - "905": { "topicTags": ["array", "two-pointers", "sorting"] }, - "906": { "topicTags": ["math", "enumeration"] }, - "907": { "topicTags": ["stack", "array", "dynamic-programming", "monotonic-stack"] }, - "908": { "topicTags": ["array", "math"] }, - "909": { "topicTags": ["breadth-first-search", "array", "matrix"] }, - "910": { "topicTags": ["greedy", "array", "math", "sorting"] }, - "911": { "topicTags": ["design", "array", "hash-table", "binary-search"] }, - "912": { "topicTags": ["array", "divide-and-conquer", "bucket-sort", "counting-sort", "radix-sort", "sorting", "heap-priority-queue", "merge-sort"] }, - "913": { "topicTags": ["graph", "topological-sort", "memoization", "math", "dynamic-programming", "game-theory"] }, - "914": { "topicTags": ["array", "hash-table", "math", "counting", "number-theory"] }, - "915": { "topicTags": ["array"] }, - "916": { "topicTags": ["array", "hash-table", "string"] }, - "917": { "topicTags": ["two-pointers", "string"] }, - "918": { "topicTags": ["queue", "array", "divide-and-conquer", "dynamic-programming", "monotonic-queue"] }, - "919": { "topicTags": ["tree", "breadth-first-search", "design", "binary-tree"] }, - "920": { "topicTags": ["math", "dynamic-programming", "combinatorics"] }, - "921": { "topicTags": ["stack", "greedy", "string"] }, - "922": { "topicTags": ["array", "two-pointers", "sorting"] }, - "923": { "topicTags": ["array", "hash-table", "two-pointers", "counting", "sorting"] }, - "924": { "topicTags": ["depth-first-search", "breadth-first-search", "union-find", "array", "matrix"] }, - "925": { "topicTags": ["two-pointers", "string"] }, - "926": { "topicTags": ["string", "dynamic-programming"] }, - "927": { "topicTags": ["array", "math"] }, - "928": { "topicTags": ["depth-first-search", "breadth-first-search", "union-find", "array", "matrix"] }, - "929": { "topicTags": ["array", "hash-table", "string"] }, - "930": { "topicTags": ["array", "hash-table", "prefix-sum", "sliding-window"] }, - "931": { "topicTags": ["array", "dynamic-programming", "matrix"] }, - "932": { "topicTags": ["array", "math", "divide-and-conquer"] }, - "933": { "topicTags": ["design", "queue", "data-stream"] }, - "934": { "topicTags": ["depth-first-search", "breadth-first-search", "array", "matrix"] }, - "935": { "topicTags": ["dynamic-programming"] }, - "936": { "topicTags": ["stack", "greedy", "queue", "string"] }, - "937": { "topicTags": ["array", "string", "sorting"] }, - "938": { "topicTags": ["tree", "depth-first-search", "binary-search-tree", "binary-tree"] }, - "939": { "topicTags": ["geometry", "array", "hash-table", "math", "sorting"] }, - "940": { "topicTags": ["string", "dynamic-programming"] }, - "941": { "topicTags": ["array"] }, - "942": { "topicTags": ["greedy", "array", "two-pointers", "string"] }, - "943": { "topicTags": ["bit-manipulation", "array", "string", "dynamic-programming", "bitmask"] }, - "944": { "topicTags": ["array", "string"] }, - "945": { "topicTags": ["greedy", "array", "counting", "sorting"] }, - "946": { "topicTags": ["stack", "array", "simulation"] }, - "947": { "topicTags": ["depth-first-search", "union-find", "graph"] }, - "948": { "topicTags": ["greedy", "array", "two-pointers", "sorting"] }, - "949": { "topicTags": ["string", "enumeration"] }, - "950": { "topicTags": ["queue", "array", "sorting", "simulation"] }, - "951": { "topicTags": ["tree", "depth-first-search", "binary-tree"] }, - "952": { "topicTags": ["union-find", "array", "math"] }, - "953": { "topicTags": ["array", "hash-table", "string"] }, - "954": { "topicTags": ["greedy", "array", "hash-table", "sorting"] }, - "955": { "topicTags": ["greedy", "array", "string"] }, - "956": { "topicTags": ["array", "dynamic-programming"] }, - "957": { "topicTags": ["bit-manipulation", "array", "hash-table", "math"] }, - "958": { "topicTags": ["tree", "breadth-first-search", "binary-tree"] }, - "959": { "topicTags": ["depth-first-search", "breadth-first-search", "union-find", "graph"] }, - "960": { "topicTags": ["array", "string", "dynamic-programming"] }, - "961": { "topicTags": ["array", "hash-table"] }, - "962": { "topicTags": ["stack", "array", "monotonic-stack"] }, - "963": { "topicTags": ["geometry", "array", "math"] }, - "964": { "topicTags": ["math", "dynamic-programming"] }, - "965": { "topicTags": ["tree", "depth-first-search", "breadth-first-search", "binary-tree"] }, - "966": { "topicTags": ["array", "hash-table", "string"] }, - "967": { "topicTags": ["breadth-first-search", "backtracking"] }, - "968": { "topicTags": ["tree", "depth-first-search", "dynamic-programming", "binary-tree"] }, - "969": { "topicTags": ["greedy", "array", "two-pointers", "sorting"] }, - "970": { "topicTags": ["hash-table", "math"] }, - "971": { "topicTags": ["tree", "depth-first-search", "binary-tree"] }, - "972": { "topicTags": ["math", "string"] }, - "973": { "topicTags": ["geometry", "array", "math", "divide-and-conquer", "quickselect", "sorting", "heap-priority-queue"] }, - "974": { "topicTags": ["array", "hash-table", "prefix-sum"] }, - "975": { "topicTags": ["stack", "array", "dynamic-programming", "ordered-set", "monotonic-stack"] }, - "976": { "topicTags": ["greedy", "array", "math", "sorting"] }, - "977": { "topicTags": ["array", "two-pointers", "sorting"] }, - "978": { "topicTags": ["array", "dynamic-programming", "sliding-window"] }, - "979": { "topicTags": ["tree", "depth-first-search", "binary-tree"] }, - "980": { "topicTags": ["bit-manipulation", "array", "backtracking", "matrix"] }, - "981": { "topicTags": ["design", "hash-table", "string", "binary-search"] }, - "982": { "topicTags": ["bit-manipulation", "array", "hash-table"] }, - "983": { "topicTags": ["array", "dynamic-programming"] }, - "984": { "topicTags": ["greedy", "string"] }, - "985": { "topicTags": ["array", "simulation"] }, - "986": { "topicTags": ["array", "two-pointers"] }, - "987": { "topicTags": ["tree", "depth-first-search", "breadth-first-search", "hash-table", "binary-tree"] }, - "988": { "topicTags": ["tree", "depth-first-search", "string", "binary-tree"] }, - "989": { "topicTags": ["array", "math"] }, - "990": { "topicTags": ["union-find", "graph", "array", "string"] }, - "991": { "topicTags": ["greedy", "math"] }, - "992": { "topicTags": ["array", "hash-table", "counting", "sliding-window"] }, - "993": { "topicTags": ["tree", "depth-first-search", "breadth-first-search", "binary-tree"] }, - "994": { "topicTags": ["breadth-first-search", "array", "matrix"] }, - "995": { "topicTags": ["bit-manipulation", "queue", "array", "prefix-sum", "sliding-window"] }, - "996": { "topicTags": ["bit-manipulation", "array", "math", "dynamic-programming", "backtracking", "bitmask"] }, - "997": { "topicTags": ["graph", "array", "hash-table"] }, - "998": { "topicTags": ["tree", "binary-tree"] }, - "999": { "topicTags": ["array", "matrix", "simulation"] }, - "1000": { "topicTags": ["array", "dynamic-programming"] }, - "1001": { "topicTags": ["array", "hash-table"] }, - "1002": { "topicTags": ["array", "hash-table", "string"] }, - "1003": { "topicTags": ["stack", "string"] }, - "1004": { "topicTags": ["array", "binary-search", "prefix-sum", "sliding-window"] }, - "1005": { "topicTags": ["greedy", "array", "sorting"] }, - "1006": { "topicTags": ["stack", "math", "simulation"] }, - "1007": { "topicTags": ["greedy", "array"] }, - "1008": { "topicTags": ["stack", "tree", "binary-search-tree", "array", "binary-tree", "monotonic-stack"] }, - "1009": { "topicTags": ["bit-manipulation"] }, - "1010": { "topicTags": ["array", "hash-table", "counting"] }, - "1011": { "topicTags": ["array", "binary-search"] }, - "1012": { "topicTags": ["math", "dynamic-programming"] }, - "1013": { "topicTags": ["greedy", "array"] }, - "1014": { "topicTags": ["array", "dynamic-programming"] }, - "1015": { "topicTags": ["hash-table", "math"] }, - "1016": { "topicTags": ["string"] }, - "1017": { "topicTags": ["math"] }, - "1018": { "topicTags": ["array"] }, - "1019": { "topicTags": ["stack", "array", "linked-list", "monotonic-stack"] }, - "1020": { "topicTags": ["depth-first-search", "breadth-first-search", "union-find", "array", "matrix"] }, - "1021": { "topicTags": ["stack", "string"] }, - "1022": { "topicTags": ["tree", "depth-first-search", "binary-tree"] }, - "1023": { "topicTags": ["trie", "two-pointers", "string", "string-matching"] }, - "1024": { "topicTags": ["greedy", "array", "dynamic-programming"] }, - "1025": { "topicTags": ["brainteaser", "math", "dynamic-programming", "game-theory"] }, - "1026": { "topicTags": ["tree", "depth-first-search", "binary-tree"] }, - "1027": { "topicTags": ["array", "hash-table", "binary-search", "dynamic-programming"] }, - "1028": { "topicTags": ["tree", "depth-first-search", "string", "binary-tree"] }, - "1029": { "topicTags": ["greedy", "array", "sorting"] }, - "1030": { "topicTags": ["geometry", "array", "math", "matrix", "sorting"] }, - "1031": { "topicTags": ["array", "dynamic-programming", "sliding-window"] }, - "1032": { "topicTags": ["design", "trie", "array", "string", "data-stream"] }, - "1033": { "topicTags": ["brainteaser", "math"] }, - "1034": { "topicTags": ["depth-first-search", "breadth-first-search", "array", "matrix"] }, - "1035": { "topicTags": ["array", "dynamic-programming"] }, - "1036": { "topicTags": ["depth-first-search", "breadth-first-search", "array", "hash-table"] }, - "1037": { "topicTags": ["geometry", "array", "math"] }, - "1038": { "topicTags": ["tree", "depth-first-search", "binary-search-tree", "binary-tree"] }, - "1039": { "topicTags": ["array", "dynamic-programming"] }, - "1040": { "topicTags": ["array", "math", "two-pointers", "sorting"] }, - "1041": { "topicTags": ["math", "string", "simulation"] }, - "1042": { "topicTags": ["depth-first-search", "breadth-first-search", "graph"] }, - "1043": { "topicTags": ["array", "dynamic-programming"] }, - "1044": { "topicTags": ["string", "binary-search", "suffix-array", "sliding-window", "hash-function", "rolling-hash"] }, - "1045": { "topicTags": ["database"] }, - "1046": { "topicTags": ["array", "heap-priority-queue"] }, - "1047": { "topicTags": ["stack", "string"] }, - "1048": { "topicTags": ["array", "hash-table", "two-pointers", "string", "dynamic-programming"] }, - "1049": { "topicTags": ["array", "dynamic-programming"] }, - "1050": { "topicTags": ["database"] }, - "1051": { "topicTags": ["array", "counting-sort", "sorting"] }, - "1052": { "topicTags": ["array", "sliding-window"] }, - "1053": { "topicTags": ["greedy", "array"] }, - "1054": { "topicTags": ["greedy", "array", "hash-table", "counting", "sorting", "heap-priority-queue"] }, - "1055": { "topicTags": ["greedy", "string", "dynamic-programming"] }, - "1056": { "topicTags": ["math"] }, - "1057": { "topicTags": ["greedy", "array", "sorting"] }, - "1058": { "topicTags": ["greedy", "array", "math", "string"] }, - "1059": { "topicTags": ["depth-first-search", "graph"] }, - "1060": { "topicTags": ["array", "binary-search"] }, - "1061": { "topicTags": ["union-find", "string"] }, - "1062": { "topicTags": ["string", "binary-search", "dynamic-programming", "suffix-array", "hash-function", "rolling-hash"] }, - "1063": { "topicTags": ["stack", "array", "monotonic-stack"] }, - "1064": { "topicTags": ["array", "binary-search"] }, - "1065": { "topicTags": ["trie", "array", "string", "sorting"] }, - "1066": { "topicTags": ["bit-manipulation", "array", "dynamic-programming", "backtracking", "bitmask"] }, - "1067": { "topicTags": ["math", "dynamic-programming"] }, - "1068": { "topicTags": ["database"] }, - "1069": { "topicTags": ["database"] }, - "1070": { "topicTags": ["database"] }, - "1071": { "topicTags": ["math", "string"] }, - "1072": { "topicTags": ["array", "hash-table", "matrix"] }, - "1073": { "topicTags": ["array", "math"] }, - "1074": { "topicTags": ["array", "hash-table", "matrix", "prefix-sum"] }, - "1075": { "topicTags": ["database"] }, - "1076": { "topicTags": ["database"] }, - "1077": { "topicTags": ["database"] }, - "1078": { "topicTags": ["string"] }, - "1079": { "topicTags": ["string", "backtracking"] }, - "1080": { "topicTags": ["tree", "depth-first-search", "binary-tree"] }, - "1081": { "topicTags": ["stack", "greedy", "string", "monotonic-stack"] }, - "1082": { "topicTags": ["database"] }, - "1083": { "topicTags": ["database"] }, - "1084": { "topicTags": ["database"] }, - "1085": { "topicTags": ["array", "math"] }, - "1086": { "topicTags": ["array", "hash-table", "sorting"] }, - "1087": { "topicTags": ["breadth-first-search", "string", "backtracking"] }, - "1088": { "topicTags": ["math", "backtracking"] }, - "1089": { "topicTags": ["array", "two-pointers"] }, - "1090": { "topicTags": ["greedy", "array", "hash-table", "counting", "sorting"] }, - "1091": { "topicTags": ["breadth-first-search", "array", "matrix"] }, - "1092": { "topicTags": ["string", "dynamic-programming"] }, - "1093": { "topicTags": ["math", "two-pointers", "probability-and-statistics"] }, - "1094": { "topicTags": ["array", "prefix-sum", "sorting", "simulation", "heap-priority-queue"] }, - "1095": { "topicTags": ["array", "binary-search", "interactive"] }, - "1096": { "topicTags": ["stack", "breadth-first-search", "string", "backtracking"] }, - "1097": { "topicTags": ["database"] }, - "1098": { "topicTags": ["database"] }, - "1099": { "topicTags": ["array", "two-pointers", "binary-search", "sorting"] }, - "1100": { "topicTags": ["hash-table", "string", "sliding-window"] }, - "1101": { "topicTags": ["union-find", "array"] }, - "1102": { "topicTags": ["depth-first-search", "breadth-first-search", "union-find", "array", "matrix", "heap-priority-queue"] }, - "1103": { "topicTags": ["math", "simulation"] }, - "1104": { "topicTags": ["tree", "math", "binary-tree"] }, - "1105": { "topicTags": ["array", "dynamic-programming"] }, - "1106": { "topicTags": ["stack", "recursion", "string"] }, - "1107": { "topicTags": ["database"] }, - "1108": { "topicTags": ["string"] }, - "1109": { "topicTags": ["array", "prefix-sum"] }, - "1110": { "topicTags": ["tree", "depth-first-search", "binary-tree"] }, - "1111": { "topicTags": ["stack", "string"] }, - "1112": { "topicTags": ["database"] }, - "1113": { "topicTags": ["database"] }, - "1114": { "topicTags": ["concurrency"] }, - "1115": { "topicTags": ["concurrency"] }, - "1116": { "topicTags": ["concurrency"] }, - "1117": { "topicTags": ["concurrency"] }, - "1118": { "topicTags": ["math"] }, - "1119": { "topicTags": ["string"] }, - "1120": { "topicTags": ["tree", "depth-first-search", "binary-tree"] }, - "1121": { "topicTags": ["greedy", "array"] }, - "1122": { "topicTags": ["array", "hash-table", "counting-sort", "sorting"] }, - "1123": { "topicTags": ["tree", "depth-first-search", "breadth-first-search", "hash-table", "binary-tree"] }, - "1124": { "topicTags": ["stack", "array", "hash-table", "prefix-sum", "monotonic-stack"] }, - "1125": { "topicTags": ["bit-manipulation", "array", "dynamic-programming", "bitmask"] }, - "1126": { "topicTags": ["database"] }, - "1127": { "topicTags": ["database"] }, - "1128": { "topicTags": ["array", "hash-table", "counting"] }, - "1129": { "topicTags": ["breadth-first-search", "graph"] }, - "1130": { "topicTags": ["stack", "greedy", "dynamic-programming", "monotonic-stack"] }, - "1131": { "topicTags": ["array", "math"] }, - "1132": { "topicTags": ["database"] }, - "1133": { "topicTags": ["array", "hash-table", "sorting"] }, - "1134": { "topicTags": ["math"] }, - "1135": { "topicTags": ["union-find", "graph", "minimum-spanning-tree", "heap-priority-queue"] }, - "1136": { "topicTags": ["graph", "topological-sort"] }, - "1137": { "topicTags": ["memoization", "math", "dynamic-programming"] }, - "1138": { "topicTags": ["hash-table", "string"] }, - "1139": { "topicTags": ["array", "dynamic-programming", "matrix"] }, - "1140": { "topicTags": ["array", "math", "dynamic-programming", "game-theory"] }, - "1141": { "topicTags": ["database"] }, - "1142": { "topicTags": ["database"] }, - "1143": { "topicTags": ["string", "dynamic-programming"] }, - "1144": { "topicTags": ["greedy", "array"] }, - "1145": { "topicTags": ["tree", "depth-first-search", "binary-tree"] }, - "1146": { "topicTags": ["design", "array", "hash-table", "binary-search"] }, - "1147": { "topicTags": ["greedy", "two-pointers", "string", "dynamic-programming", "hash-function", "rolling-hash"] }, - "1148": { "topicTags": ["database"] }, - "1149": { "topicTags": ["database"] }, - "1150": { "topicTags": ["array", "binary-search"] }, - "1151": { "topicTags": ["array", "sliding-window"] }, - "1152": { "topicTags": ["array", "hash-table", "sorting"] }, - "1153": { "topicTags": ["hash-table", "string"] }, - "1154": { "topicTags": ["math", "string"] }, - "1155": { "topicTags": ["dynamic-programming"] }, - "1156": { "topicTags": ["string", "sliding-window"] }, - "1157": { "topicTags": ["design", "binary-indexed-tree", "segment-tree", "array", "binary-search"] }, - "1158": { "topicTags": ["database"] }, - "1159": { "topicTags": ["database"] }, - "1160": { "topicTags": ["array", "hash-table", "string"] }, - "1161": { "topicTags": ["tree", "depth-first-search", "breadth-first-search", "binary-tree"] }, - "1162": { "topicTags": ["breadth-first-search", "array", "dynamic-programming", "matrix"] }, - "1163": { "topicTags": ["two-pointers", "string"] }, - "1164": { "topicTags": ["database"] }, - "1165": { "topicTags": ["hash-table", "string"] }, - "1166": { "topicTags": ["design", "trie", "hash-table", "string"] }, - "1167": { "topicTags": ["greedy", "array", "heap-priority-queue"] }, - "1168": { "topicTags": ["union-find", "graph", "minimum-spanning-tree"] }, - "1169": { "topicTags": ["array", "hash-table", "string", "sorting"] }, - "1170": { "topicTags": ["array", "hash-table", "string", "binary-search", "sorting"] }, - "1171": { "topicTags": ["hash-table", "linked-list"] }, - "1172": { "topicTags": ["stack", "design", "hash-table", "heap-priority-queue"] }, - "1173": { "topicTags": ["database"] }, - "1174": { "topicTags": ["database"] }, - "1175": { "topicTags": ["math"] }, - "1176": { "topicTags": ["array", "sliding-window"] }, - "1177": { "topicTags": ["bit-manipulation", "hash-table", "string", "prefix-sum"] }, - "1178": { "topicTags": ["bit-manipulation", "trie", "array", "hash-table", "string"] }, - "1179": { "topicTags": ["database"] }, - "1180": { "topicTags": ["math", "string"] }, - "1181": { "topicTags": ["array", "hash-table", "string", "sorting"] }, - "1182": { "topicTags": ["array", "binary-search", "dynamic-programming"] }, - "1183": { "topicTags": ["greedy", "heap-priority-queue"] }, - "1184": { "topicTags": ["array"] }, - "1185": { "topicTags": ["math"] }, - "1186": { "topicTags": ["array", "dynamic-programming"] }, - "1187": { "topicTags": ["array", "binary-search", "dynamic-programming"] }, - "1188": { "topicTags": ["concurrency"] }, - "1189": { "topicTags": ["hash-table", "string", "counting"] }, - "1190": { "topicTags": ["stack", "string"] }, - "1191": { "topicTags": ["array", "dynamic-programming"] }, - "1192": { "topicTags": ["depth-first-search", "graph", "biconnected-component"] }, - "1193": { "topicTags": ["database"] }, - "1194": { "topicTags": ["database"] }, - "1195": { "topicTags": ["concurrency"] }, - "1196": { "topicTags": ["greedy", "array", "sorting"] }, - "1197": { "topicTags": ["breadth-first-search"] }, - "1198": { "topicTags": ["array", "hash-table", "binary-search", "counting", "matrix"] }, - "1199": { "topicTags": ["greedy", "math", "heap-priority-queue"] }, - "1200": { "topicTags": ["array", "sorting"] }, - "1201": { "topicTags": ["math", "binary-search", "number-theory"] }, - "1202": { "topicTags": ["depth-first-search", "breadth-first-search", "union-find", "hash-table", "string"] }, - "1203": { "topicTags": ["depth-first-search", "breadth-first-search", "graph", "topological-sort"] }, - "1204": { "topicTags": ["database"] }, - "1205": { "topicTags": ["database"] }, - "1206": { "topicTags": ["design", "linked-list"] }, - "1207": { "topicTags": ["array", "hash-table"] }, - "1208": { "topicTags": ["string", "binary-search", "prefix-sum", "sliding-window"] }, - "1209": { "topicTags": ["stack", "string"] }, - "1210": { "topicTags": ["breadth-first-search", "array", "matrix"] }, - "1211": { "topicTags": ["database"] }, - "1212": { "topicTags": ["database"] }, - "1213": { "topicTags": ["array", "hash-table", "binary-search", "counting"] }, - "1214": { "topicTags": ["stack", "tree", "depth-first-search", "binary-search-tree", "two-pointers", "binary-search", "binary-tree"] }, - "1215": { "topicTags": ["breadth-first-search", "backtracking"] }, - "1216": { "topicTags": ["string", "dynamic-programming"] }, - "1217": { "topicTags": ["greedy", "array", "math"] }, - "1218": { "topicTags": ["array", "hash-table", "dynamic-programming"] }, - "1219": { "topicTags": ["array", "backtracking", "matrix"] }, - "1220": { "topicTags": ["dynamic-programming"] }, - "1221": { "topicTags": ["greedy", "string", "counting"] }, - "1222": { "topicTags": ["array", "matrix", "simulation"] }, - "1223": { "topicTags": ["array", "dynamic-programming"] }, - "1224": { "topicTags": ["array", "hash-table"] }, - "1225": { "topicTags": ["database"] }, - "1226": { "topicTags": ["concurrency"] }, - "1227": { "topicTags": ["brainteaser", "math", "dynamic-programming", "probability-and-statistics"] }, - "1228": { "topicTags": ["array", "math"] }, - "1229": { "topicTags": ["array", "two-pointers", "sorting"] }, - "1230": { "topicTags": ["math", "dynamic-programming", "probability-and-statistics"] }, - "1231": { "topicTags": ["array", "binary-search"] }, - "1232": { "topicTags": ["geometry", "array", "math"] }, - "1233": { "topicTags": ["trie", "array", "string"] }, - "1234": { "topicTags": ["string", "sliding-window"] }, - "1235": { "topicTags": ["array", "binary-search", "dynamic-programming", "sorting"] }, - "1236": { "topicTags": ["depth-first-search", "breadth-first-search", "string", "interactive"] }, - "1237": { "topicTags": ["math", "two-pointers", "binary-search", "interactive"] }, - "1238": { "topicTags": ["bit-manipulation", "math", "backtracking"] }, - "1239": { "topicTags": ["bit-manipulation", "array", "string", "backtracking"] }, - "1240": { "topicTags": ["dynamic-programming", "backtracking"] }, - "1241": { "topicTags": ["database"] }, - "1242": { "topicTags": ["depth-first-search", "breadth-first-search", "concurrency"] }, - "1243": { "topicTags": ["array", "simulation"] }, - "1244": { "topicTags": ["design", "hash-table", "sorting"] }, - "1245": { "topicTags": ["tree", "depth-first-search", "breadth-first-search", "graph", "topological-sort"] }, - "1246": { "topicTags": ["array", "dynamic-programming"] }, - "1247": { "topicTags": ["greedy", "math", "string"] }, - "1248": { "topicTags": ["array", "hash-table", "math", "sliding-window"] }, - "1249": { "topicTags": ["stack", "string"] }, - "1250": { "topicTags": ["array", "math", "number-theory"] }, - "1251": { "topicTags": ["database"] }, - "1252": { "topicTags": ["array", "math", "simulation"] }, - "1253": { "topicTags": ["greedy", "array", "matrix"] }, - "1254": { "topicTags": ["depth-first-search", "breadth-first-search", "union-find", "array", "matrix"] }, - "1255": { "topicTags": ["bit-manipulation", "array", "string", "dynamic-programming", "backtracking", "bitmask"] }, - "1256": { "topicTags": ["bit-manipulation", "math", "string"] }, - "1257": { "topicTags": ["tree", "depth-first-search", "breadth-first-search", "array", "hash-table", "string"] }, - "1258": { "topicTags": ["union-find", "array", "hash-table", "string", "backtracking"] }, - "1259": { "topicTags": ["math", "dynamic-programming"] }, - "1260": { "topicTags": ["array", "matrix", "simulation"] }, - "1261": { "topicTags": ["tree", "depth-first-search", "breadth-first-search", "design", "hash-table", "binary-tree"] }, - "1262": { "topicTags": ["greedy", "array", "dynamic-programming"] }, - "1263": { "topicTags": ["breadth-first-search", "array", "matrix", "heap-priority-queue"] }, - "1264": { "topicTags": ["database"] }, - "1265": { "topicTags": ["stack", "recursion", "linked-list", "two-pointers"] }, - "1266": { "topicTags": ["geometry", "array", "math"] }, - "1267": { "topicTags": ["depth-first-search", "breadth-first-search", "union-find", "array", "counting", "matrix"] }, - "1268": { "topicTags": ["trie", "array", "string"] }, - "1269": { "topicTags": ["dynamic-programming"] }, - "1270": { "topicTags": ["database"] }, - "1271": { "topicTags": ["math", "string"] }, - "1272": { "topicTags": ["array"] }, - "1273": { "topicTags": ["tree", "depth-first-search", "breadth-first-search"] }, - "1274": { "topicTags": ["array", "divide-and-conquer", "interactive"] }, - "1275": { "topicTags": ["array", "hash-table", "matrix", "simulation"] }, - "1276": { "topicTags": ["math"] }, - "1277": { "topicTags": ["array", "dynamic-programming", "matrix"] }, - "1278": { "topicTags": ["string", "dynamic-programming"] }, - "1279": { "topicTags": ["concurrency"] }, - "1280": { "topicTags": ["database"] }, - "1281": { "topicTags": ["math"] }, - "1282": { "topicTags": ["array", "hash-table"] }, - "1283": { "topicTags": ["array", "binary-search"] }, - "1284": { "topicTags": ["bit-manipulation", "breadth-first-search", "array", "matrix"] }, - "1285": { "topicTags": ["database"] }, - "1286": { "topicTags": ["design", "string", "backtracking", "iterator"] }, - "1287": { "topicTags": ["array"] }, - "1288": { "topicTags": ["array", "sorting"] }, - "1289": { "topicTags": ["array", "dynamic-programming", "matrix"] }, - "1290": { "topicTags": ["linked-list", "math"] }, - "1291": { "topicTags": ["enumeration"] }, - "1292": { "topicTags": ["array", "binary-search", "matrix", "prefix-sum"] }, - "1293": { "topicTags": ["breadth-first-search", "array", "matrix"] }, - "1294": { "topicTags": ["database"] }, - "1295": { "topicTags": ["array"] }, - "1296": { "topicTags": ["greedy", "array", "hash-table", "sorting"] }, - "1297": { "topicTags": ["hash-table", "string", "sliding-window"] }, - "1298": { "topicTags": ["breadth-first-search", "array"] }, - "1299": { "topicTags": ["array"] }, - "1300": { "topicTags": ["array", "binary-search", "sorting"] }, - "1301": { "topicTags": ["array", "dynamic-programming", "matrix"] }, - "1302": { "topicTags": ["tree", "depth-first-search", "breadth-first-search", "binary-tree"] }, - "1303": { "topicTags": ["database"] }, - "1304": { "topicTags": ["array", "math"] }, - "1305": { "topicTags": ["tree", "depth-first-search", "binary-search-tree", "binary-tree", "sorting"] }, - "1306": { "topicTags": ["depth-first-search", "breadth-first-search", "array"] }, - "1307": { "topicTags": ["array", "math", "string", "backtracking"] }, - "1308": { "topicTags": ["database"] }, - "1309": { "topicTags": ["string"] }, - "1310": { "topicTags": ["bit-manipulation", "array", "prefix-sum"] }, - "1311": { "topicTags": ["breadth-first-search", "array", "hash-table", "sorting"] }, - "1312": { "topicTags": ["string", "dynamic-programming"] }, - "1313": { "topicTags": ["array"] }, - "1314": { "topicTags": ["array", "matrix", "prefix-sum"] }, - "1315": { "topicTags": ["tree", "depth-first-search", "breadth-first-search", "binary-tree"] }, - "1316": { "topicTags": ["trie", "string", "hash-function", "rolling-hash"] }, - "1317": { "topicTags": ["math"] }, - "1318": { "topicTags": ["bit-manipulation"] }, - "1319": { "topicTags": ["depth-first-search", "breadth-first-search", "union-find", "graph"] }, - "1320": { "topicTags": ["string", "dynamic-programming"] }, - "1321": { "topicTags": ["database"] }, - "1322": { "topicTags": ["database"] }, - "1323": { "topicTags": ["greedy", "math"] }, - "1324": { "topicTags": ["array", "string", "simulation"] }, - "1325": { "topicTags": ["tree", "depth-first-search", "binary-tree"] }, - "1326": { "topicTags": ["greedy", "array", "dynamic-programming"] }, - "1327": { "topicTags": ["database"] }, - "1328": { "topicTags": ["greedy", "string"] }, - "1329": { "topicTags": ["array", "matrix", "sorting"] }, - "1330": { "topicTags": ["greedy", "array", "math"] }, - "1331": { "topicTags": ["array", "hash-table", "sorting"] }, - "1332": { "topicTags": ["two-pointers", "string"] }, - "1333": { "topicTags": ["array", "sorting"] }, - "1334": { "topicTags": ["graph", "dynamic-programming", "shortest-path"] }, - "1335": { "topicTags": ["array", "dynamic-programming"] }, - "1336": { "topicTags": ["database"] }, - "1337": { "topicTags": ["array", "binary-search", "matrix", "sorting", "heap-priority-queue"] }, - "1338": { "topicTags": ["greedy", "array", "hash-table", "sorting", "heap-priority-queue"] }, - "1339": { "topicTags": ["tree", "depth-first-search", "binary-tree"] }, - "1340": { "topicTags": ["array", "dynamic-programming", "sorting"] }, - "1341": { "topicTags": ["database"] }, - "1342": { "topicTags": ["bit-manipulation", "math"] }, - "1343": { "topicTags": ["array", "sliding-window"] }, - "1344": { "topicTags": ["math"] }, - "1345": { "topicTags": ["breadth-first-search", "array", "hash-table"] }, - "1346": { "topicTags": ["array", "hash-table", "two-pointers", "binary-search", "sorting"] }, - "1347": { "topicTags": ["hash-table", "string", "counting"] }, - "1348": { "topicTags": ["design", "hash-table", "binary-search", "ordered-set", "sorting"] }, - "1349": { "topicTags": ["bit-manipulation", "array", "dynamic-programming", "bitmask", "matrix"] }, - "1350": { "topicTags": ["database"] }, - "1351": { "topicTags": ["array", "binary-search", "matrix"] }, - "1352": { "topicTags": ["design", "queue", "array", "math", "data-stream"] }, - "1353": { "topicTags": ["greedy", "array", "heap-priority-queue"] }, - "1354": { "topicTags": ["array", "heap-priority-queue"] }, - "1355": { "topicTags": ["database"] }, - "1356": { "topicTags": ["bit-manipulation", "array", "counting", "sorting"] }, - "1357": { "topicTags": ["design", "array", "hash-table"] }, - "1358": { "topicTags": ["hash-table", "string", "sliding-window"] }, - "1359": { "topicTags": ["math", "dynamic-programming", "combinatorics"] }, - "1360": { "topicTags": ["math", "string"] }, - "1361": { "topicTags": ["tree", "depth-first-search", "breadth-first-search", "union-find", "graph", "binary-tree"] }, - "1362": { "topicTags": ["math"] }, - "1363": { "topicTags": ["greedy", "array", "dynamic-programming"] }, - "1364": { "topicTags": ["database"] }, - "1365": { "topicTags": ["array", "hash-table", "counting", "sorting"] }, - "1366": { "topicTags": ["array", "hash-table", "string", "counting", "sorting"] }, - "1367": { "topicTags": ["tree", "depth-first-search", "breadth-first-search", "linked-list", "binary-tree"] }, - "1368": { "topicTags": ["breadth-first-search", "graph", "array", "matrix", "shortest-path", "heap-priority-queue"] }, - "1369": { "topicTags": ["database"] }, - "1370": { "topicTags": ["hash-table", "string", "counting"] }, - "1371": { "topicTags": ["bit-manipulation", "hash-table", "string", "prefix-sum"] }, - "1372": { "topicTags": ["tree", "depth-first-search", "dynamic-programming", "binary-tree"] }, - "1373": { "topicTags": ["tree", "depth-first-search", "binary-search-tree", "dynamic-programming", "binary-tree"] }, - "1374": { "topicTags": ["string"] }, - "1375": { "topicTags": ["array"] }, - "1376": { "topicTags": ["tree", "depth-first-search", "breadth-first-search"] }, - "1377": { "topicTags": ["tree", "depth-first-search", "breadth-first-search", "graph"] }, - "1378": { "topicTags": ["database"] }, - "1379": { "topicTags": ["tree", "depth-first-search", "breadth-first-search", "binary-tree"] }, - "1380": { "topicTags": ["array", "matrix"] }, - "1381": { "topicTags": ["stack", "design", "array"] }, - "1382": { "topicTags": ["greedy", "tree", "depth-first-search", "binary-search-tree", "divide-and-conquer", "binary-tree"] }, - "1383": { "topicTags": ["greedy", "array", "sorting", "heap-priority-queue"] }, - "1384": { "topicTags": ["database"] }, - "1385": { "topicTags": ["array", "two-pointers", "binary-search", "sorting"] }, - "1386": { "topicTags": ["greedy", "bit-manipulation", "array", "hash-table"] }, - "1387": { "topicTags": ["memoization", "dynamic-programming", "sorting"] }, - "1388": { "topicTags": ["greedy", "array", "dynamic-programming", "heap-priority-queue"] }, - "1389": { "topicTags": ["array", "simulation"] }, - "1390": { "topicTags": ["array", "math"] }, - "1391": { "topicTags": ["depth-first-search", "breadth-first-search", "union-find", "array", "matrix"] }, - "1392": { "topicTags": ["string", "string-matching", "hash-function", "rolling-hash"] }, - "1393": { "topicTags": ["database"] }, - "1394": { "topicTags": ["array", "hash-table", "counting"] }, - "1395": { "topicTags": ["binary-indexed-tree", "array", "dynamic-programming"] }, - "1396": { "topicTags": ["design", "hash-table", "string"] }, - "1397": { "topicTags": ["string", "dynamic-programming", "string-matching"] }, - "1398": { "topicTags": ["database"] }, - "1399": { "topicTags": ["hash-table", "math"] }, - "1400": { "topicTags": ["greedy", "hash-table", "string", "counting"] }, - "1401": { "topicTags": ["geometry", "math"] }, - "1402": { "topicTags": ["greedy", "array", "dynamic-programming", "sorting"] }, - "1403": { "topicTags": ["greedy", "array", "sorting"] }, - "1404": { "topicTags": ["bit-manipulation", "string"] }, - "1405": { "topicTags": ["greedy", "string", "heap-priority-queue"] }, - "1406": { "topicTags": ["array", "math", "dynamic-programming", "game-theory"] }, - "1407": { "topicTags": ["database"] }, - "1408": { "topicTags": ["string", "string-matching"] }, - "1409": { "topicTags": ["binary-indexed-tree", "array", "simulation"] }, - "1410": { "topicTags": ["hash-table", "string"] }, - "1411": { "topicTags": ["dynamic-programming"] }, - "1412": { "topicTags": ["database"] }, - "1413": { "topicTags": ["array", "prefix-sum"] }, - "1414": { "topicTags": ["greedy"] }, - "1415": { "topicTags": ["string", "backtracking"] }, - "1416": { "topicTags": ["string", "dynamic-programming"] }, - "1417": { "topicTags": ["string"] }, - "1418": { "topicTags": ["array", "hash-table", "string", "ordered-set", "sorting"] }, - "1419": { "topicTags": ["string", "counting"] }, - "1420": { "topicTags": ["dynamic-programming"] }, - "1421": { "topicTags": ["database"] }, - "1422": { "topicTags": ["string"] }, - "1423": { "topicTags": ["array", "prefix-sum", "sliding-window"] }, - "1424": { "topicTags": ["array", "sorting", "heap-priority-queue"] }, - "1425": { "topicTags": ["queue", "array", "dynamic-programming", "sliding-window", "monotonic-queue", "heap-priority-queue"] }, - "1426": { "topicTags": ["array", "hash-table"] }, - "1427": { "topicTags": ["array", "math", "string"] }, - "1428": { "topicTags": ["array", "binary-search", "interactive", "matrix"] }, - "1429": { "topicTags": ["design", "queue", "array", "hash-table", "data-stream"] }, - "1430": { "topicTags": ["tree", "depth-first-search", "breadth-first-search", "binary-tree"] }, - "1431": { "topicTags": ["array"] }, - "1432": { "topicTags": ["greedy", "math"] }, - "1433": { "topicTags": ["greedy", "string", "sorting"] }, - "1434": { "topicTags": ["bit-manipulation", "array", "dynamic-programming", "bitmask"] }, - "1435": { "topicTags": ["database"] }, - "1436": { "topicTags": ["hash-table", "string"] }, - "1437": { "topicTags": ["array"] }, - "1438": { "topicTags": ["queue", "array", "ordered-set", "sliding-window", "monotonic-queue", "heap-priority-queue"] }, - "1439": { "topicTags": ["array", "binary-search", "matrix", "heap-priority-queue"] }, - "1440": { "topicTags": ["database"] }, - "1441": { "topicTags": ["stack", "array", "simulation"] }, - "1442": { "topicTags": ["bit-manipulation", "array", "hash-table", "math", "prefix-sum"] }, - "1443": { "topicTags": ["tree", "depth-first-search", "breadth-first-search", "hash-table"] }, - "1444": { "topicTags": ["memoization", "array", "dynamic-programming", "matrix"] }, - "1445": { "topicTags": ["database"] }, - "1446": { "topicTags": ["string"] }, - "1447": { "topicTags": ["math", "string", "number-theory"] }, - "1448": { "topicTags": ["tree", "depth-first-search", "breadth-first-search", "binary-tree"] }, - "1449": { "topicTags": ["array", "dynamic-programming"] }, - "1450": { "topicTags": ["array"] }, - "1451": { "topicTags": ["string", "sorting"] }, - "1452": { "topicTags": ["array", "hash-table", "string"] }, - "1453": { "topicTags": ["geometry", "array", "math"] }, - "1454": { "topicTags": ["database"] }, - "1455": { "topicTags": ["string", "string-matching"] }, - "1456": { "topicTags": ["string", "sliding-window"] }, - "1457": { "topicTags": ["bit-manipulation", "tree", "depth-first-search", "breadth-first-search", "binary-tree"] }, - "1458": { "topicTags": ["array", "dynamic-programming"] }, - "1459": { "topicTags": ["database"] }, - "1460": { "topicTags": ["array", "hash-table", "sorting"] }, - "1461": { "topicTags": ["bit-manipulation", "hash-table", "string", "hash-function", "rolling-hash"] }, - "1462": { "topicTags": ["depth-first-search", "breadth-first-search", "graph", "topological-sort"] }, - "1463": { "topicTags": ["array", "dynamic-programming", "matrix"] }, - "1464": { "topicTags": ["array", "sorting", "heap-priority-queue"] }, - "1465": { "topicTags": ["greedy", "array", "sorting"] }, - "1466": { "topicTags": ["depth-first-search", "breadth-first-search", "graph"] }, - "1467": { "topicTags": ["math", "dynamic-programming", "backtracking", "combinatorics", "probability-and-statistics"] }, - "1468": { "topicTags": ["database"] }, - "1469": { "topicTags": ["tree", "depth-first-search", "breadth-first-search", "binary-tree"] }, - "1470": { "topicTags": ["array"] }, - "1471": { "topicTags": ["array", "two-pointers", "sorting"] }, - "1472": { "topicTags": ["stack", "design", "array", "linked-list", "data-stream", "doubly-linked-list"] }, - "1473": { "topicTags": ["array", "dynamic-programming"] }, - "1474": { "topicTags": ["linked-list"] }, - "1475": { "topicTags": ["stack", "array", "monotonic-stack"] }, - "1476": { "topicTags": ["design", "array", "matrix"] }, - "1477": { "topicTags": ["array", "hash-table", "binary-search", "dynamic-programming", "sliding-window"] }, - "1478": { "topicTags": ["array", "math", "dynamic-programming", "sorting"] }, - "1479": { "topicTags": ["database"] }, - "1480": { "topicTags": ["array", "prefix-sum"] }, - "1481": { "topicTags": ["greedy", "array", "hash-table", "counting", "sorting"] }, - "1482": { "topicTags": ["array", "binary-search"] }, - "1483": { "topicTags": ["tree", "depth-first-search", "breadth-first-search", "design", "binary-search", "dynamic-programming"] }, - "1484": { "topicTags": ["database"] }, - "1485": { "topicTags": ["tree", "depth-first-search", "breadth-first-search", "hash-table", "binary-tree"] }, - "1486": { "topicTags": ["bit-manipulation", "math"] }, - "1487": { "topicTags": ["array", "hash-table", "string"] }, - "1488": { "topicTags": ["greedy", "array", "hash-table", "binary-search", "heap-priority-queue"] }, - "1489": { "topicTags": ["union-find", "graph", "minimum-spanning-tree", "sorting", "strongly-connected-component"] }, - "1490": { "topicTags": ["tree", "depth-first-search", "breadth-first-search", "hash-table"] }, - "1491": { "topicTags": ["array", "sorting"] }, - "1492": { "topicTags": ["math"] }, - "1493": { "topicTags": ["array", "dynamic-programming", "sliding-window"] }, - "1494": { "topicTags": ["bit-manipulation", "graph", "dynamic-programming", "bitmask"] }, - "1495": { "topicTags": ["database"] }, - "1496": { "topicTags": ["hash-table", "string"] }, - "1497": { "topicTags": ["array", "hash-table", "counting"] }, - "1498": { "topicTags": ["array", "two-pointers", "binary-search", "sorting"] }, - "1499": { "topicTags": ["queue", "array", "sliding-window", "monotonic-queue", "heap-priority-queue"] }, - "1500": { "topicTags": ["design", "hash-table", "data-stream", "heap-priority-queue"] }, - "1501": { "topicTags": ["database"] }, - "1502": { "topicTags": ["array", "sorting"] }, - "1503": { "topicTags": ["brainteaser", "array", "simulation"] }, - "1504": { "topicTags": ["stack", "array", "dynamic-programming", "matrix", "monotonic-stack"] }, - "1505": { "topicTags": ["greedy", "binary-indexed-tree", "segment-tree", "string"] }, - "1506": { "topicTags": ["bit-manipulation", "tree", "depth-first-search", "hash-table"] }, - "1507": { "topicTags": ["string"] }, - "1508": { "topicTags": ["array", "two-pointers", "binary-search", "sorting"] }, - "1509": { "topicTags": ["greedy", "array", "sorting"] }, - "1510": { "topicTags": ["math", "dynamic-programming", "game-theory"] }, - "1511": { "topicTags": ["database"] }, - "1512": { "topicTags": ["array", "hash-table", "math", "counting"] }, - "1513": { "topicTags": ["math", "string"] }, - "1514": { "topicTags": ["graph", "shortest-path", "heap-priority-queue"] }, - "1515": { "topicTags": ["geometry", "math", "randomized"] }, - "1516": { "topicTags": ["tree", "depth-first-search"] }, - "1517": { "topicTags": ["database"] }, - "1518": { "topicTags": ["math", "simulation"] }, - "1519": { "topicTags": ["tree", "depth-first-search", "breadth-first-search", "hash-table", "counting"] }, - "1520": { "topicTags": ["greedy", "string"] }, - "1521": { "topicTags": ["bit-manipulation", "segment-tree", "array", "binary-search"] }, - "1522": { "topicTags": ["tree", "depth-first-search"] }, - "1523": { "topicTags": ["math"] }, - "1524": { "topicTags": ["array", "math", "dynamic-programming", "prefix-sum"] }, - "1525": { "topicTags": ["bit-manipulation", "string", "dynamic-programming"] }, - "1526": { "topicTags": ["stack", "greedy", "array", "dynamic-programming", "monotonic-stack"] }, - "1527": { "topicTags": ["database"] }, - "1528": { "topicTags": ["array", "string"] }, - "1529": { "topicTags": ["greedy", "string"] }, - "1530": { "topicTags": ["tree", "depth-first-search", "binary-tree"] }, - "1531": { "topicTags": ["string", "dynamic-programming"] }, - "1532": { "topicTags": ["database"] }, - "1533": { "topicTags": ["array", "binary-search", "interactive"] }, - "1534": { "topicTags": ["array", "enumeration"] }, - "1535": { "topicTags": ["array", "simulation"] }, - "1536": { "topicTags": ["greedy", "array", "matrix"] }, - "1537": { "topicTags": ["greedy", "array", "two-pointers", "dynamic-programming"] }, - "1538": { "topicTags": ["array", "math", "interactive"] }, - "1539": { "topicTags": ["array", "binary-search"] }, - "1540": { "topicTags": ["hash-table", "string"] }, - "1541": { "topicTags": ["stack", "greedy", "string"] }, - "1542": { "topicTags": ["bit-manipulation", "hash-table", "string"] }, - "1543": { "topicTags": ["database"] }, - "1544": { "topicTags": ["stack", "string"] }, - "1545": { "topicTags": ["recursion", "string"] }, - "1546": { "topicTags": ["greedy", "array", "hash-table", "prefix-sum"] }, - "1547": { "topicTags": ["array", "dynamic-programming"] }, - "1548": { "topicTags": ["graph", "dynamic-programming"] }, - "1549": { "topicTags": ["database"] }, - "1550": { "topicTags": ["array"] }, - "1551": { "topicTags": ["math"] }, - "1552": { "topicTags": ["array", "binary-search", "sorting"] }, - "1553": { "topicTags": ["memoization", "dynamic-programming"] }, - "1554": { "topicTags": ["hash-table", "string", "hash-function", "rolling-hash"] }, - "1555": { "topicTags": ["database"] }, - "1556": { "topicTags": ["string"] }, - "1557": { "topicTags": ["graph"] }, - "1558": { "topicTags": ["greedy", "array"] }, - "1559": { "topicTags": ["depth-first-search", "breadth-first-search", "union-find", "array", "matrix"] }, - "1560": { "topicTags": ["array", "simulation"] }, - "1561": { "topicTags": ["greedy", "array", "math", "game-theory", "sorting"] }, - "1562": { "topicTags": ["array", "binary-search", "simulation"] }, - "1563": { "topicTags": ["array", "math", "dynamic-programming", "game-theory"] }, - "1564": { "topicTags": ["greedy", "array", "sorting"] }, - "1565": { "topicTags": ["database"] }, - "1566": { "topicTags": ["array", "enumeration"] }, - "1567": { "topicTags": ["greedy", "array", "dynamic-programming"] }, - "1568": { "topicTags": ["depth-first-search", "breadth-first-search", "array", "matrix", "strongly-connected-component"] }, - "1569": { "topicTags": ["tree", "union-find", "binary-search-tree", "memoization", "array", "math", "divide-and-conquer", "dynamic-programming", "binary-tree", "combinatorics"] }, - "1570": { "topicTags": ["design", "array", "hash-table", "two-pointers"] }, - "1571": { "topicTags": ["database"] }, - "1572": { "topicTags": ["array", "matrix"] }, - "1573": { "topicTags": ["math", "string"] }, - "1574": { "topicTags": ["stack", "array", "two-pointers", "binary-search", "monotonic-stack"] }, - "1575": { "topicTags": ["memoization", "array", "dynamic-programming"] }, - "1576": { "topicTags": ["string"] }, - "1577": { "topicTags": ["array", "hash-table", "math", "two-pointers"] }, - "1578": { "topicTags": ["greedy", "array", "string", "dynamic-programming"] }, - "1579": { "topicTags": ["union-find", "graph"] }, - "1580": { "topicTags": ["greedy", "array", "sorting"] }, - "1581": { "topicTags": ["database"] }, - "1582": { "topicTags": ["array", "matrix"] }, - "1583": { "topicTags": ["array", "simulation"] }, - "1584": { "topicTags": ["union-find", "array", "minimum-spanning-tree"] }, - "1585": { "topicTags": ["greedy", "string", "sorting"] }, - "1586": { "topicTags": ["stack", "tree", "design", "binary-search-tree", "binary-tree", "iterator"] }, - "1587": { "topicTags": ["database"] }, - "1588": { "topicTags": ["array", "math", "prefix-sum"] }, - "1589": { "topicTags": ["greedy", "array", "prefix-sum", "sorting"] }, - "1590": { "topicTags": ["array", "hash-table", "prefix-sum"] }, - "1591": { "topicTags": ["graph", "topological-sort", "array", "matrix"] }, - "1592": { "topicTags": ["string"] }, - "1593": { "topicTags": ["hash-table", "string", "backtracking"] }, - "1594": { "topicTags": ["array", "dynamic-programming", "matrix"] }, - "1595": { "topicTags": ["bit-manipulation", "array", "dynamic-programming", "bitmask", "matrix"] }, - "1596": { "topicTags": ["database"] }, - "1597": { "topicTags": ["stack", "tree", "string", "binary-tree"] }, - "1598": { "topicTags": ["stack", "array", "string"] }, - "1599": { "topicTags": ["array", "simulation"] }, - "1600": { "topicTags": ["tree", "depth-first-search", "design", "hash-table"] }, - "1601": { "topicTags": ["bit-manipulation", "array", "backtracking", "enumeration"] }, - "1602": { "topicTags": ["tree", "breadth-first-search", "binary-tree"] }, - "1603": { "topicTags": ["design", "counting", "simulation"] }, - "1604": { "topicTags": ["array", "hash-table", "string", "sorting"] }, - "1605": { "topicTags": ["greedy", "array", "matrix"] }, - "1606": { "topicTags": ["greedy", "array", "ordered-set", "heap-priority-queue"] }, - "1607": { "topicTags": ["database"] }, - "1608": { "topicTags": ["array", "binary-search", "sorting"] }, - "1609": { "topicTags": ["tree", "breadth-first-search", "binary-tree"] }, - "1610": { "topicTags": ["geometry", "array", "math", "sorting", "sliding-window"] }, - "1611": { "topicTags": ["bit-manipulation", "memoization", "dynamic-programming"] }, - "1612": { "topicTags": ["tree", "depth-first-search", "binary-tree"] }, - "1613": { "topicTags": ["database"] }, - "1614": { "topicTags": ["stack", "string"] }, - "1615": { "topicTags": ["graph"] }, - "1616": { "topicTags": ["two-pointers", "string"] }, - "1617": { "topicTags": ["bit-manipulation", "tree", "dynamic-programming", "bitmask", "enumeration"] }, - "1618": { "topicTags": ["array", "string", "binary-search", "interactive"] }, - "1619": { "topicTags": ["array", "sorting"] }, - "1620": { "topicTags": ["array", "enumeration"] }, - "1621": { "topicTags": ["math", "dynamic-programming"] }, - "1622": { "topicTags": ["design", "segment-tree", "math"] }, - "1623": { "topicTags": ["database"] }, - "1624": { "topicTags": ["hash-table", "string"] }, - "1625": { "topicTags": ["breadth-first-search", "string"] }, - "1626": { "topicTags": ["array", "dynamic-programming", "sorting"] }, - "1627": { "topicTags": ["union-find", "array", "math"] }, - "1628": { "topicTags": ["stack", "tree", "design", "math", "binary-tree"] }, - "1629": { "topicTags": ["array", "string"] }, - "1630": { "topicTags": ["array", "sorting"] }, - "1631": { "topicTags": ["depth-first-search", "breadth-first-search", "union-find", "array", "binary-search", "matrix", "heap-priority-queue"] }, - "1632": { "topicTags": ["greedy", "union-find", "graph", "topological-sort", "array", "matrix"] }, - "1633": { "topicTags": ["database"] }, - "1634": { "topicTags": ["linked-list", "math", "two-pointers"] }, - "1635": { "topicTags": ["database"] }, - "1636": { "topicTags": ["array", "hash-table", "sorting"] }, - "1637": { "topicTags": ["array", "sorting"] }, - "1638": { "topicTags": ["hash-table", "string", "dynamic-programming"] }, - "1639": { "topicTags": ["array", "string", "dynamic-programming"] }, - "1640": { "topicTags": ["array", "hash-table"] }, - "1641": { "topicTags": ["dynamic-programming"] }, - "1642": { "topicTags": ["greedy", "array", "heap-priority-queue"] }, - "1643": { "topicTags": ["array", "math", "dynamic-programming", "combinatorics"] }, - "1644": { "topicTags": ["tree", "depth-first-search", "binary-tree"] }, - "1645": { "topicTags": ["database"] }, - "1646": { "topicTags": ["array", "dynamic-programming", "simulation"] }, - "1647": { "topicTags": ["greedy", "string", "sorting"] }, - "1648": { "topicTags": ["greedy", "array", "math", "binary-search", "sorting", "heap-priority-queue"] }, - "1649": { "topicTags": ["binary-indexed-tree", "segment-tree", "array", "binary-search", "divide-and-conquer", "ordered-set", "merge-sort"] }, - "1650": { "topicTags": ["tree", "hash-table", "binary-tree"] }, - "1651": { "topicTags": ["database"] }, - "1652": { "topicTags": ["array"] }, - "1653": { "topicTags": ["stack", "string", "dynamic-programming"] }, - "1654": { "topicTags": ["breadth-first-search", "array", "dynamic-programming"] }, - "1655": { "topicTags": ["bit-manipulation", "array", "dynamic-programming", "backtracking", "bitmask"] }, - "1656": { "topicTags": ["design", "array", "hash-table", "data-stream"] }, - "1657": { "topicTags": ["hash-table", "string", "sorting"] }, - "1658": { "topicTags": ["array", "hash-table", "binary-search", "prefix-sum", "sliding-window"] }, - "1659": { "topicTags": ["bit-manipulation", "memoization", "dynamic-programming", "bitmask"] }, - "1660": { "topicTags": ["tree", "depth-first-search", "breadth-first-search", "hash-table", "binary-tree"] }, - "1661": { "topicTags": ["database"] }, - "1662": { "topicTags": ["array", "string"] }, - "1663": { "topicTags": ["greedy", "string"] }, - "1664": { "topicTags": ["array", "dynamic-programming"] }, - "1665": { "topicTags": ["greedy", "array", "sorting"] }, - "1666": { "topicTags": ["tree", "depth-first-search", "binary-tree"] }, - "1667": { "topicTags": ["database"] }, - "1668": { "topicTags": ["string", "string-matching"] }, - "1669": { "topicTags": ["linked-list"] }, - "1670": { "topicTags": ["design", "queue", "array", "linked-list", "data-stream"] }, - "1671": { "topicTags": ["greedy", "array", "binary-search", "dynamic-programming"] }, - "1672": { "topicTags": ["array", "matrix"] }, - "1673": { "topicTags": ["stack", "greedy", "array", "monotonic-stack"] }, - "1674": { "topicTags": ["array", "hash-table", "prefix-sum"] }, - "1675": { "topicTags": ["greedy", "array", "ordered-set", "heap-priority-queue"] }, - "1676": { "topicTags": ["tree", "depth-first-search", "binary-tree"] }, - "1677": { "topicTags": ["database"] }, - "1678": { "topicTags": ["string"] }, - "1679": { "topicTags": ["array", "hash-table", "two-pointers", "sorting"] }, - "1680": { "topicTags": ["bit-manipulation", "math", "simulation"] }, - "1681": { "topicTags": ["bit-manipulation", "array", "dynamic-programming", "bitmask"] }, - "1682": { "topicTags": ["string", "dynamic-programming"] }, - "1683": { "topicTags": ["database"] }, - "1684": { "topicTags": ["bit-manipulation", "array", "hash-table", "string"] }, - "1685": { "topicTags": ["array", "math", "prefix-sum"] }, - "1686": { "topicTags": ["greedy", "array", "math", "game-theory", "sorting", "heap-priority-queue"] }, - "1687": { "topicTags": ["segment-tree", "queue", "array", "dynamic-programming", "monotonic-queue", "heap-priority-queue"] }, - "1688": { "topicTags": ["math", "simulation"] }, - "1689": { "topicTags": ["greedy", "string"] }, - "1690": { "topicTags": ["array", "math", "dynamic-programming", "game-theory"] }, - "1691": { "topicTags": ["array", "dynamic-programming", "sorting"] }, - "1692": { "topicTags": ["dynamic-programming"] }, - "1693": { "topicTags": ["database"] }, - "1694": { "topicTags": ["string"] }, - "1695": { "topicTags": ["array", "hash-table", "sliding-window"] }, - "1696": { "topicTags": ["queue", "array", "dynamic-programming", "sliding-window", "monotonic-queue", "heap-priority-queue"] }, - "1697": { "topicTags": ["union-find", "graph", "array", "sorting"] }, - "1698": { "topicTags": ["trie", "string", "suffix-array", "hash-function", "rolling-hash"] }, - "1699": { "topicTags": ["database"] }, - "1700": { "topicTags": ["stack", "queue", "array", "simulation"] }, - "1701": { "topicTags": ["array", "simulation"] }, - "1702": { "topicTags": ["greedy", "string"] }, - "1703": { "topicTags": ["greedy", "array", "prefix-sum", "sliding-window"] }, - "1704": { "topicTags": ["string", "counting"] }, - "1705": { "topicTags": ["greedy", "array", "heap-priority-queue"] }, - "1706": { "topicTags": ["depth-first-search", "array", "dynamic-programming", "matrix", "simulation"] }, - "1707": { "topicTags": ["bit-manipulation", "trie", "array"] }, - "1708": { "topicTags": ["greedy", "array"] }, - "1709": { "topicTags": ["database"] }, - "1710": { "topicTags": ["greedy", "array", "sorting"] }, - "1711": { "topicTags": ["array", "hash-table"] }, - "1712": { "topicTags": ["array", "two-pointers", "binary-search", "prefix-sum"] }, - "1713": { "topicTags": ["greedy", "array", "hash-table", "binary-search"] }, - "1714": { "topicTags": ["array", "dynamic-programming"] }, - "1715": { "topicTags": ["database"] }, - "1716": { "topicTags": ["math"] }, - "1717": { "topicTags": ["stack", "greedy", "string"] }, - "1718": { "topicTags": ["array", "backtracking"] }, - "1719": { "topicTags": ["tree", "graph", "topological-sort"] }, - "1720": { "topicTags": ["bit-manipulation", "array"] }, - "1721": { "topicTags": ["linked-list", "two-pointers"] }, - "1722": { "topicTags": ["depth-first-search", "union-find", "array"] }, - "1723": { "topicTags": ["bit-manipulation", "array", "dynamic-programming", "backtracking", "bitmask"] }, - "1724": { "topicTags": ["union-find", "graph", "minimum-spanning-tree"] }, - "1725": { "topicTags": ["array"] }, - "1726": { "topicTags": ["array", "hash-table"] }, - "1727": { "topicTags": ["greedy", "array", "matrix", "sorting"] }, - "1728": { "topicTags": ["graph", "topological-sort", "memoization", "array", "math", "dynamic-programming", "game-theory", "matrix"] }, - "1729": { "topicTags": ["database"] }, - "1730": { "topicTags": ["breadth-first-search", "array", "matrix"] }, - "1731": { "topicTags": ["database"] }, - "1732": { "topicTags": ["array", "prefix-sum"] }, - "1733": { "topicTags": ["greedy", "array"] }, - "1734": { "topicTags": ["bit-manipulation", "array"] }, - "1735": { "topicTags": ["array", "math", "dynamic-programming", "combinatorics", "number-theory"] }, - "1736": { "topicTags": ["string"] }, - "1737": { "topicTags": ["hash-table", "string", "counting", "prefix-sum"] }, - "1738": { "topicTags": ["bit-manipulation", "array", "divide-and-conquer", "matrix", "prefix-sum", "quickselect", "heap-priority-queue"] }, - "1739": { "topicTags": ["greedy", "math", "binary-search"] }, - "1740": { "topicTags": ["tree", "depth-first-search", "breadth-first-search", "hash-table", "binary-tree"] }, - "1741": { "topicTags": ["database"] }, - "1742": { "topicTags": ["hash-table", "math", "counting"] }, - "1743": { "topicTags": ["array", "hash-table"] }, - "1744": { "topicTags": ["array", "prefix-sum"] }, - "1745": { "topicTags": ["string", "dynamic-programming"] }, - "1746": { "topicTags": ["array", "dynamic-programming"] }, - "1747": { "topicTags": ["database"] }, - "1748": { "topicTags": ["array", "hash-table", "counting"] }, - "1749": { "topicTags": ["array", "dynamic-programming"] }, - "1750": { "topicTags": ["two-pointers", "string"] }, - "1751": { "topicTags": ["array", "binary-search", "dynamic-programming"] }, - "1752": { "topicTags": ["array"] }, - "1753": { "topicTags": ["greedy", "math", "heap-priority-queue"] }, - "1754": { "topicTags": ["greedy", "two-pointers", "string"] }, - "1755": { "topicTags": ["bit-manipulation", "array", "two-pointers", "dynamic-programming", "bitmask"] }, - "1756": { "topicTags": ["stack", "design", "binary-indexed-tree", "array", "hash-table", "ordered-set"] }, - "1757": { "topicTags": ["database"] }, - "1758": { "topicTags": ["string"] }, - "1759": { "topicTags": ["math", "string"] }, - "1760": { "topicTags": ["array", "binary-search"] }, - "1761": { "topicTags": ["graph"] }, - "1762": { "topicTags": ["stack", "array", "monotonic-stack"] }, - "1763": { "topicTags": ["bit-manipulation", "hash-table", "string", "divide-and-conquer", "sliding-window"] }, - "1764": { "topicTags": ["greedy", "array", "string-matching"] }, - "1765": { "topicTags": ["breadth-first-search", "array", "matrix"] }, - "1766": { "topicTags": ["tree", "depth-first-search", "breadth-first-search", "math"] }, - "1767": { "topicTags": ["database"] }, - "1768": { "topicTags": ["two-pointers", "string"] }, - "1769": { "topicTags": ["array", "string"] }, - "1770": { "topicTags": ["array", "dynamic-programming"] }, - "1771": { "topicTags": ["string", "dynamic-programming"] }, - "1772": { "topicTags": ["array", "hash-table", "string", "sorting"] }, - "1773": { "topicTags": ["array", "string"] }, - "1774": { "topicTags": ["array", "dynamic-programming", "backtracking"] }, - "1775": { "topicTags": ["greedy", "array", "hash-table", "counting"] }, - "1776": { "topicTags": ["stack", "array", "math", "monotonic-stack", "heap-priority-queue"] }, - "1777": { "topicTags": ["database"] }, - "1778": { "topicTags": ["depth-first-search", "breadth-first-search", "graph", "interactive"] }, - "1779": { "topicTags": ["array"] }, - "1780": { "topicTags": ["math"] }, - "1781": { "topicTags": ["hash-table", "string", "counting"] }, - "1782": { "topicTags": ["graph", "two-pointers", "binary-search"] }, - "1783": { "topicTags": ["database"] }, - "1784": { "topicTags": ["string"] }, - "1785": { "topicTags": ["greedy", "array"] }, - "1786": { "topicTags": ["graph", "topological-sort", "dynamic-programming", "shortest-path", "heap-priority-queue"] }, - "1787": { "topicTags": ["bit-manipulation", "array", "dynamic-programming"] }, - "1788": { "topicTags": ["greedy", "array", "prefix-sum"] }, - "1789": { "topicTags": ["database"] }, - "1790": { "topicTags": ["hash-table", "string", "counting"] }, - "1791": { "topicTags": ["graph"] }, - "1792": { "topicTags": ["greedy", "array", "heap-priority-queue"] }, - "1793": { "topicTags": ["stack", "array", "two-pointers", "binary-search", "monotonic-stack"] }, - "1794": { "topicTags": ["greedy", "hash-table", "string"] }, - "1795": { "topicTags": ["database"] }, - "1796": { "topicTags": ["hash-table", "string"] }, - "1797": { "topicTags": ["design", "hash-table"] }, - "1798": { "topicTags": ["greedy", "array"] }, - "1799": { "topicTags": ["bit-manipulation", "array", "math", "dynamic-programming", "backtracking", "bitmask", "number-theory"] }, - "1800": { "topicTags": ["array"] }, - "1801": { "topicTags": ["array", "simulation", "heap-priority-queue"] }, - "1802": { "topicTags": ["greedy", "binary-search"] }, - "1803": { "topicTags": ["bit-manipulation", "trie", "array"] }, - "1804": { "topicTags": ["design", "trie", "hash-table", "string"] }, - "1805": { "topicTags": ["hash-table", "string"] }, - "1806": { "topicTags": ["array", "math", "simulation"] }, - "1807": { "topicTags": ["array", "hash-table", "string"] }, - "1808": { "topicTags": ["recursion", "math"] }, - "1809": { "topicTags": ["database"] }, - "1810": { "topicTags": ["depth-first-search", "breadth-first-search", "graph", "interactive", "heap-priority-queue"] }, - "1811": { "topicTags": ["database"] }, - "1812": { "topicTags": ["math", "string"] }, - "1813": { "topicTags": ["array", "two-pointers", "string"] }, - "1814": { "topicTags": ["array", "hash-table", "math", "counting"] }, - "1815": { "topicTags": ["bit-manipulation", "memoization", "array", "dynamic-programming", "bitmask"] }, - "1816": { "topicTags": ["array", "string"] }, - "1817": { "topicTags": ["array", "hash-table"] }, - "1818": { "topicTags": ["array", "binary-search", "ordered-set", "sorting"] }, - "1819": { "topicTags": ["array", "math", "counting", "number-theory"] }, - "1820": { "topicTags": ["array", "backtracking", "matrix"] }, - "1821": { "topicTags": ["database"] }, - "1822": { "topicTags": ["array", "math"] }, - "1823": { "topicTags": ["recursion", "queue", "array", "math", "simulation"] }, - "1824": { "topicTags": ["greedy", "array", "dynamic-programming"] }, - "1825": { "topicTags": ["design", "queue", "data-stream", "ordered-set", "heap-priority-queue"] }, - "1826": { "topicTags": ["array", "two-pointers"] }, - "1827": { "topicTags": ["greedy", "array"] }, - "1828": { "topicTags": ["geometry", "array", "math"] }, - "1829": { "topicTags": ["bit-manipulation", "array", "prefix-sum"] }, - "1830": { "topicTags": ["math", "string", "combinatorics"] }, - "1831": { "topicTags": ["database"] }, - "1832": { "topicTags": ["hash-table", "string"] }, - "1833": { "topicTags": ["greedy", "array", "sorting"] }, - "1834": { "topicTags": ["array", "sorting", "heap-priority-queue"] }, - "1835": { "topicTags": ["bit-manipulation", "array", "math"] }, - "1836": { "topicTags": ["hash-table", "linked-list"] }, - "1837": { "topicTags": ["math"] }, - "1838": { "topicTags": ["array", "binary-search", "prefix-sum", "sliding-window"] }, - "1839": { "topicTags": ["string", "sliding-window"] }, - "1840": { "topicTags": ["array", "math"] }, - "1841": { "topicTags": ["database"] }, - "1842": { "topicTags": ["two-pointers", "string"] }, - "1843": { "topicTags": ["database"] }, - "1844": { "topicTags": ["string"] }, - "1845": { "topicTags": ["design", "heap-priority-queue"] }, - "1846": { "topicTags": ["greedy", "array", "sorting"] }, - "1847": { "topicTags": ["array", "binary-search", "sorting"] }, - "1848": { "topicTags": ["array"] }, - "1849": { "topicTags": ["string", "backtracking"] }, - "1850": { "topicTags": ["greedy", "two-pointers", "string"] }, - "1851": { "topicTags": ["array", "binary-search", "sorting", "line-sweep", "heap-priority-queue"] }, - "1852": { "topicTags": ["array", "hash-table", "sliding-window"] }, - "1853": { "topicTags": ["database"] }, - "1854": { "topicTags": ["array", "counting"] }, - "1855": { "topicTags": ["greedy", "array", "two-pointers", "binary-search"] }, - "1856": { "topicTags": ["stack", "array", "prefix-sum", "monotonic-stack"] }, - "1857": { "topicTags": ["graph", "topological-sort", "memoization", "hash-table", "dynamic-programming", "counting"] }, - "1858": { "topicTags": ["depth-first-search", "trie"] }, - "1859": { "topicTags": ["string", "sorting"] }, - "1860": { "topicTags": ["simulation"] }, - "1861": { "topicTags": ["array", "two-pointers", "matrix"] }, - "1862": { "topicTags": ["array", "math", "binary-search", "prefix-sum"] }, - "1863": { "topicTags": ["bit-manipulation", "array", "math", "backtracking", "combinatorics"] }, - "1864": { "topicTags": ["greedy", "string"] }, - "1865": { "topicTags": ["design", "array", "hash-table"] }, - "1866": { "topicTags": ["math", "dynamic-programming", "combinatorics"] }, - "1867": { "topicTags": ["database"] }, - "1868": { "topicTags": ["array", "two-pointers"] }, - "1869": { "topicTags": ["string"] }, - "1870": { "topicTags": ["array", "binary-search"] }, - "1871": { "topicTags": ["two-pointers", "string", "prefix-sum"] }, - "1872": { "topicTags": ["array", "math", "dynamic-programming", "game-theory", "prefix-sum"] }, - "1873": { "topicTags": ["database"] }, - "1874": { "topicTags": ["greedy", "array", "sorting"] }, - "1875": { "topicTags": ["database"] }, - "1876": { "topicTags": ["hash-table", "string", "counting", "sliding-window"] }, - "1877": { "topicTags": ["greedy", "array", "two-pointers", "sorting"] }, - "1878": { "topicTags": ["array", "math", "matrix", "prefix-sum", "sorting", "heap-priority-queue"] }, - "1879": { "topicTags": ["bit-manipulation", "array", "dynamic-programming", "bitmask"] }, - "1880": { "topicTags": ["string"] }, - "1881": { "topicTags": ["greedy", "string"] }, - "1882": { "topicTags": ["array", "heap-priority-queue"] }, - "1883": { "topicTags": ["array", "dynamic-programming"] }, - "1884": { "topicTags": ["math", "dynamic-programming"] }, - "1885": { "topicTags": ["array", "binary-search", "sorting"] }, - "1886": { "topicTags": ["array", "matrix"] }, - "1887": { "topicTags": ["array", "sorting"] }, - "1888": { "topicTags": ["greedy", "string", "dynamic-programming", "sliding-window"] }, - "1889": { "topicTags": ["array", "binary-search", "prefix-sum", "sorting"] }, - "1890": { "topicTags": ["database"] }, - "1891": { "topicTags": ["array", "binary-search"] }, - "1892": { "topicTags": ["database"] }, - "1893": { "topicTags": ["array", "hash-table", "prefix-sum"] }, - "1894": { "topicTags": ["array", "binary-search", "prefix-sum", "simulation"] }, - "1895": { "topicTags": ["array", "matrix", "prefix-sum"] }, - "1896": { "topicTags": ["stack", "math", "string", "dynamic-programming"] }, - "1897": { "topicTags": ["hash-table", "string", "counting"] }, - "1898": { "topicTags": ["array", "string", "binary-search"] }, - "1899": { "topicTags": ["greedy", "array"] }, - "1900": { "topicTags": ["memoization", "dynamic-programming"] }, - "1901": { "topicTags": ["array", "binary-search", "matrix"] }, - "1902": { "topicTags": ["tree", "binary-search-tree", "binary-tree", "ordered-set"] }, - "1903": { "topicTags": ["greedy", "math", "string"] }, - "1904": { "topicTags": ["math", "string"] }, - "1905": { "topicTags": ["depth-first-search", "breadth-first-search", "union-find", "array", "matrix"] }, - "1906": { "topicTags": ["array", "hash-table"] }, - "1907": { "topicTags": ["database"] }, - "1908": { "topicTags": ["bit-manipulation", "brainteaser", "array", "math", "dynamic-programming", "game-theory"] }, - "1909": { "topicTags": ["array"] }, - "1910": { "topicTags": ["string"] }, - "1911": { "topicTags": ["array", "dynamic-programming"] }, - "1912": { "topicTags": ["design", "array", "hash-table", "ordered-set", "heap-priority-queue"] }, - "1913": { "topicTags": ["array", "sorting"] }, - "1914": { "topicTags": ["array", "matrix", "simulation"] }, - "1915": { "topicTags": ["bit-manipulation", "hash-table", "string", "prefix-sum"] }, - "1916": { "topicTags": ["tree", "graph", "topological-sort", "math", "dynamic-programming", "combinatorics"] }, - "1917": { "topicTags": ["database"] }, - "1918": { "topicTags": ["array", "binary-search", "sliding-window"] }, - "1919": { "topicTags": ["database"] }, - "1920": { "topicTags": ["array", "simulation"] }, - "1921": { "topicTags": ["greedy", "array", "sorting"] }, - "1922": { "topicTags": ["recursion", "math"] }, - "1923": { "topicTags": ["array", "binary-search", "suffix-array", "hash-function", "rolling-hash"] }, - "1924": { "topicTags": ["geometry", "array", "math"] }, - "1925": { "topicTags": ["math", "enumeration"] }, - "1926": { "topicTags": ["breadth-first-search", "array", "matrix"] }, - "1927": { "topicTags": ["greedy", "math", "game-theory"] }, - "1928": { "topicTags": ["graph", "dynamic-programming"] }, - "1929": { "topicTags": ["array"] }, - "1930": { "topicTags": ["hash-table", "string", "prefix-sum"] }, - "1931": { "topicTags": ["dynamic-programming"] }, - "1932": { "topicTags": ["tree", "depth-first-search", "hash-table", "binary-search", "binary-tree"] }, - "1933": { "topicTags": ["string"] }, - "1934": { "topicTags": ["database"] }, - "1935": { "topicTags": ["hash-table", "string"] }, - "1936": { "topicTags": ["greedy", "array"] }, - "1937": { "topicTags": [] }, - "1938": { "topicTags": [] }, - "1939": { "topicTags": ["database"] }, - "1940": { "topicTags": ["array", "hash-table", "counting"] }, - "1941": { "topicTags": ["hash-table", "string", "counting"] }, - "1942": { "topicTags": ["array", "ordered-set", "heap-priority-queue"] }, - "1943": { "topicTags": ["array", "prefix-sum"] }, - "1944": { "topicTags": ["stack", "array", "monotonic-stack"] }, - "1945": { "topicTags": ["string", "simulation"] }, - "1946": { "topicTags": ["greedy", "array", "string"] }, - "1947": { "topicTags": ["bit-manipulation", "array", "dynamic-programming", "backtracking", "bitmask"] }, - "1948": { "topicTags": ["trie", "array", "hash-table", "string", "hash-function"] }, - "1949": { "topicTags": ["database"] }, - "1950": { "topicTags": ["stack", "array", "monotonic-stack"] }, - "1951": { "topicTags": ["database"] }, - "1952": { "topicTags": ["math"] }, - "1953": { "topicTags": ["greedy", "array"] }, - "1954": { "topicTags": ["math", "binary-search"] }, - "1955": { "topicTags": ["array", "dynamic-programming"] }, - "1956": { "topicTags": ["geometry", "array", "math", "binary-search", "enumeration"] }, - "1957": { "topicTags": ["string"] }, - "1958": { "topicTags": ["array", "enumeration", "matrix"] }, - "1959": { "topicTags": ["array", "dynamic-programming"] }, - "1960": { "topicTags": ["string", "hash-function", "rolling-hash"] }, - "1961": { "topicTags": ["array", "string"] }, - "1962": { "topicTags": ["array", "heap-priority-queue"] }, - "1963": { "topicTags": ["stack", "greedy", "two-pointers", "string"] }, - "1964": { "topicTags": ["binary-indexed-tree", "array", "binary-search"] }, - "1965": { "topicTags": ["database"] }, - "1966": { "topicTags": ["array", "binary-search"] }, - "1967": { "topicTags": ["string"] }, - "1968": { "topicTags": ["greedy", "array", "sorting"] }, - "1969": { "topicTags": ["greedy", "recursion", "math"] }, - "1970": { "topicTags": ["depth-first-search", "breadth-first-search", "union-find", "array", "binary-search", "matrix"] }, - "1971": { "topicTags": ["depth-first-search", "breadth-first-search", "union-find", "graph"] }, - "1972": { "topicTags": ["database"] }, - "1973": { "topicTags": [] }, - "1974": { "topicTags": ["greedy", "string"] }, - "1975": { "topicTags": ["greedy", "array", "matrix"] }, - "1976": { "topicTags": ["graph", "topological-sort", "dynamic-programming", "shortest-path"] }, - "1977": { "topicTags": ["string", "dynamic-programming", "suffix-array"] }, - "1978": { "topicTags": [] }, - "1979": { "topicTags": ["array", "math", "number-theory"] }, - "1980": { "topicTags": ["array", "string", "backtracking"] }, - "1981": { "topicTags": ["array", "dynamic-programming", "matrix"] }, - "1982": { "topicTags": ["array", "divide-and-conquer"] }, - "1983": { "topicTags": ["array", "hash-table", "prefix-sum"] }, - "1984": { "topicTags": ["array", "sorting", "sliding-window"] }, - "1985": { "topicTags": ["array", "string", "divide-and-conquer", "quickselect", "sorting", "heap-priority-queue"] }, - "1986": { "topicTags": ["bit-manipulation", "array", "dynamic-programming", "backtracking", "bitmask"] }, - "1987": { "topicTags": ["string", "dynamic-programming"] }, - "1988": { "topicTags": [] }, - "1989": { "topicTags": [] }, - "1990": { "topicTags": [] }, - "1991": { "topicTags": ["array", "prefix-sum"] }, - "1992": { "topicTags": ["depth-first-search", "breadth-first-search", "array", "matrix"] }, - "1993": { "topicTags": ["tree", "depth-first-search", "breadth-first-search", "design", "hash-table"] }, - "1994": { "topicTags": ["bit-manipulation", "array", "math", "dynamic-programming", "bitmask"] }, - "1995": { "topicTags": ["array", "enumeration"] }, - "1996": { "topicTags": ["stack", "greedy", "array", "sorting", "monotonic-stack"] }, - "1997": { "topicTags": ["array", "dynamic-programming"] }, - "1998": { "topicTags": ["union-find", "array", "math", "sorting"] }, - "1999": { "topicTags": [] }, - "2000": { "topicTags": ["two-pointers", "string"] }, - "2001": { "topicTags": ["array", "hash-table", "math", "counting", "number-theory"] }, - "2002": { "topicTags": ["bit-manipulation", "string", "dynamic-programming", "backtracking", "bitmask"] }, - "2003": { "topicTags": ["tree", "depth-first-search", "union-find", "dynamic-programming"] }, - "2004": { "topicTags": [] }, - "2005": { "topicTags": [] }, - "2006": { "topicTags": ["array", "hash-table", "counting"] }, - "2007": { "topicTags": ["greedy", "array", "hash-table", "sorting"] }, - "2008": { "topicTags": ["array", "binary-search", "dynamic-programming", "sorting"] }, - "2009": { "topicTags": ["array", "binary-search"] }, - "2010": { "topicTags": [] }, - "2011": { "topicTags": ["array", "string", "simulation"] }, - "2012": { "topicTags": ["array"] }, - "2013": { "topicTags": ["design", "array", "hash-table", "counting"] }, - "2014": { "topicTags": ["greedy", "string", "backtracking", "counting", "enumeration"] }, - "2015": { "topicTags": ["greedy", "array", "sorting", "heap-priority-queue"] }, - "2016": { "topicTags": ["array"] }, - "2017": { "topicTags": ["array", "matrix", "prefix-sum"] }, - "2018": { "topicTags": ["array", "enumeration", "matrix"] }, - "2019": { "topicTags": ["stack", "memoization", "array", "math", "string", "dynamic-programming"] }, - "2020": { "topicTags": ["database"] }, - "2021": { "topicTags": ["array", "ordered-set", "prefix-sum"] }, - "2022": { "topicTags": ["array", "matrix", "simulation"] }, - "2023": { "topicTags": ["array", "string"] }, - "2024": { "topicTags": ["string", "binary-search", "prefix-sum", "sliding-window"] }, - "2025": { "topicTags": ["array", "hash-table", "counting", "enumeration", "prefix-sum"] }, - "2026": { "topicTags": ["database"] }, - "2027": { "topicTags": ["greedy", "string"] }, - "2028": { "topicTags": ["array", "math", "simulation"] }, - "2029": { "topicTags": ["greedy", "array", "math", "counting", "game-theory"] }, - "2030": { "topicTags": ["stack", "greedy", "string", "monotonic-stack"] }, - "2031": { "topicTags": ["binary-indexed-tree", "segment-tree", "array", "binary-search", "divide-and-conquer", "ordered-set", "merge-sort"] }, - "2032": { "topicTags": ["array", "hash-table"] }, - "2033": { "topicTags": ["array", "math", "matrix", "sorting"] }, - "2034": { "topicTags": ["design", "hash-table", "data-stream", "ordered-set", "heap-priority-queue"] }, - "2035": { "topicTags": ["bit-manipulation", "array", "two-pointers", "binary-search", "dynamic-programming", "bitmask", "ordered-set"] }, - "2036": { "topicTags": ["array", "dynamic-programming"] }, - "2037": { "topicTags": ["array", "sorting"] }, - "2038": { "topicTags": ["greedy", "math", "string", "game-theory"] }, - "2039": { "topicTags": ["breadth-first-search", "graph", "array"] }, - "2040": { "topicTags": ["array", "binary-search"] }, - "2041": { "topicTags": ["database"] }, - "2042": { "topicTags": ["string"] }, - "2043": { "topicTags": ["design", "array", "hash-table", "simulation"] }, - "2044": { "topicTags": ["bit-manipulation", "array", "backtracking"] }, - "2045": { "topicTags": ["breadth-first-search", "graph", "shortest-path"] }, - "2046": { "topicTags": ["linked-list", "two-pointers", "sorting"] }, - "2047": { "topicTags": ["string"] }, - "2048": { "topicTags": ["math", "backtracking", "enumeration"] }, - "2049": { "topicTags": ["tree", "depth-first-search", "array", "binary-tree"] }, - "2050": { "topicTags": ["graph", "topological-sort", "dynamic-programming"] }, - "2051": { "topicTags": ["database"] }, - "2052": { "topicTags": ["array", "dynamic-programming"] }, - "2053": { "topicTags": ["array", "hash-table", "string", "counting"] }, - "2054": { "topicTags": ["array", "binary-search", "dynamic-programming", "sorting", "heap-priority-queue"] }, - "2055": { "topicTags": ["array", "string", "binary-search", "prefix-sum"] }, - "2056": { "topicTags": ["array", "string", "backtracking", "simulation"] }, - "2057": { "topicTags": ["array"] }, - "2058": { "topicTags": ["linked-list"] }, - "2059": { "topicTags": ["breadth-first-search", "array"] }, - "2060": { "topicTags": ["string", "dynamic-programming"] }, - "2061": { "topicTags": ["array", "matrix", "simulation"] }, - "2062": { "topicTags": ["hash-table", "string"] }, - "2063": { "topicTags": ["math", "string", "dynamic-programming", "combinatorics"] }, - "2064": { "topicTags": ["array", "binary-search"] }, - "2065": { "topicTags": ["graph", "array", "backtracking"] }, - "2066": { "topicTags": ["database"] }, - "2067": { "topicTags": ["string", "counting", "prefix-sum"] }, - "2068": { "topicTags": ["hash-table", "string", "counting"] }, - "2069": { "topicTags": ["design", "simulation"] }, - "2070": { "topicTags": ["array", "binary-search", "sorting"] }, - "2071": { "topicTags": ["greedy", "queue", "array", "binary-search", "sorting", "monotonic-queue"] }, - "2072": { "topicTags": ["database"] }, - "2073": { "topicTags": ["queue", "array", "simulation"] }, - "2074": { "topicTags": ["linked-list"] }, - "2075": { "topicTags": ["string", "simulation"] }, - "2076": { "topicTags": ["union-find", "graph"] }, - "2077": { "topicTags": ["graph"] }, - "2078": { "topicTags": ["greedy", "array"] }, - "2079": { "topicTags": ["array"] }, - "2080": { "topicTags": ["design", "segment-tree", "array", "hash-table", "binary-search"] }, - "2081": { "topicTags": ["math", "enumeration"] }, - "2082": { "topicTags": ["database"] }, - "2083": { "topicTags": ["hash-table", "math", "string", "counting", "prefix-sum"] }, - "2084": { "topicTags": ["database"] }, - "2085": { "topicTags": ["array", "hash-table", "string", "counting"] }, - "2086": { "topicTags": ["greedy", "string", "dynamic-programming"] }, - "2087": { "topicTags": ["greedy", "array", "matrix"] }, - "2088": { "topicTags": ["array", "dynamic-programming", "matrix"] }, - "2089": { "topicTags": ["array", "binary-search", "sorting"] }, - "2090": { "topicTags": ["array", "sliding-window"] }, - "2091": { "topicTags": ["greedy", "array"] }, - "2092": { "topicTags": ["depth-first-search", "breadth-first-search", "union-find", "graph", "sorting"] }, - "2093": { "topicTags": ["graph", "shortest-path"] }, - "2094": { "topicTags": ["array", "hash-table", "enumeration", "sorting"] }, - "2095": { "topicTags": ["linked-list", "two-pointers"] }, - "2096": { "topicTags": ["tree", "depth-first-search", "string", "binary-tree"] }, - "2097": { "topicTags": ["depth-first-search", "graph", "eulerian-circuit"] }, - "2098": { "topicTags": ["greedy", "array", "sorting"] }, - "2099": { "topicTags": ["array", "hash-table", "sorting", "heap-priority-queue"] }, - "2100": { "topicTags": ["array", "dynamic-programming", "prefix-sum"] }, - "2101": { "topicTags": ["depth-first-search", "breadth-first-search", "graph", "geometry", "array", "math"] }, - "2102": { "topicTags": ["design", "data-stream", "ordered-set", "heap-priority-queue"] }, - "2103": { "topicTags": ["hash-table", "string"] }, - "2104": { "topicTags": ["stack", "array", "monotonic-stack"] }, - "2105": { "topicTags": ["array", "two-pointers", "simulation"] }, - "2106": { "topicTags": ["array", "binary-search", "prefix-sum", "sliding-window"] }, - "2107": { "topicTags": ["array", "hash-table", "sliding-window"] }, - "2108": { "topicTags": ["array", "two-pointers", "string"] }, - "2109": { "topicTags": ["array", "string", "simulation"] }, - "2110": { "topicTags": ["array", "math", "dynamic-programming"] }, - "2111": { "topicTags": ["array", "binary-search"] }, - "2112": { "topicTags": ["database"] }, - "2113": { "topicTags": ["array"] }, - "2114": { "topicTags": ["array", "string"] }, - "2115": { "topicTags": ["graph", "topological-sort", "array", "hash-table", "string"] }, - "2116": { "topicTags": ["stack", "greedy", "string"] }, - "2117": { "topicTags": ["math"] }, - "2118": { "topicTags": ["database"] }, - "2119": { "topicTags": ["math"] }, - "2120": { "topicTags": ["string", "simulation"] }, - "2121": { "topicTags": ["array", "hash-table", "prefix-sum"] }, - "2122": { "topicTags": ["array", "hash-table", "enumeration", "sorting"] }, - "2123": { "topicTags": ["graph", "array", "matrix"] }, - "2124": { "topicTags": ["string"] }, - "2125": { "topicTags": ["array", "math", "string", "matrix"] }, - "2126": { "topicTags": ["greedy", "array", "sorting"] }, - "2127": { "topicTags": ["depth-first-search", "graph", "topological-sort"] }, - "2128": { "topicTags": ["bit-manipulation", "array", "math", "matrix"] }, - "2129": { "topicTags": ["string"] }, - "2130": { "topicTags": ["stack", "linked-list", "two-pointers"] }, - "2131": { "topicTags": ["greedy", "array", "hash-table", "string", "counting"] }, - "2132": { "topicTags": ["greedy", "array", "matrix", "prefix-sum"] }, - "2133": { "topicTags": ["array", "hash-table", "matrix"] }, - "2134": { "topicTags": ["array", "sliding-window"] }, - "2135": { "topicTags": ["bit-manipulation", "array", "hash-table", "string", "sorting"] }, - "2136": { "topicTags": ["greedy", "array", "sorting"] }, - "2137": { "topicTags": ["array", "binary-search"] }, - "2138": { "topicTags": ["string", "simulation"] }, - "2139": { "topicTags": ["greedy", "math"] }, - "2140": { "topicTags": ["array", "dynamic-programming"] }, - "2141": { "topicTags": ["greedy", "array", "binary-search", "sorting"] }, - "2142": { "topicTags": ["database"] }, - "2143": { "topicTags": ["array", "dynamic-programming"] }, - "2144": { "topicTags": ["greedy", "array", "sorting"] }, - "2145": { "topicTags": ["array", "prefix-sum"] }, - "2146": { "topicTags": ["breadth-first-search", "array", "matrix", "sorting", "heap-priority-queue"] }, - "2147": { "topicTags": ["math", "string", "dynamic-programming"] }, - "2148": { "topicTags": ["array", "sorting"] }, - "2149": { "topicTags": ["array", "two-pointers", "simulation"] }, - "2150": { "topicTags": ["array", "hash-table", "counting"] }, - "2151": { "topicTags": ["bit-manipulation", "array", "backtracking", "enumeration"] }, - "2152": { "topicTags": ["bit-manipulation", "geometry", "array", "hash-table", "math", "dynamic-programming", "backtracking", "bitmask"] }, - "2153": { "topicTags": ["database"] }, - "2154": { "topicTags": ["array", "hash-table", "sorting", "simulation"] }, - "2155": { "topicTags": ["array"] }, - "2156": { "topicTags": ["string", "sliding-window", "hash-function", "rolling-hash"] }, - "2157": { "topicTags": ["bit-manipulation", "union-find", "string"] }, - "2158": { "topicTags": ["segment-tree", "array", "ordered-set"] }, - "2159": { "topicTags": ["database"] }, - "2160": { "topicTags": ["greedy", "math", "sorting"] }, - "2161": { "topicTags": ["array", "two-pointers", "simulation"] }, - "2162": { "topicTags": ["math", "enumeration"] }, - "2163": { "topicTags": ["array", "dynamic-programming", "heap-priority-queue"] }, - "2164": { "topicTags": ["array", "sorting"] }, - "2165": { "topicTags": ["math", "sorting"] }, - "2166": { "topicTags": ["design", "array", "hash-table"] }, - "2167": { "topicTags": ["string", "dynamic-programming"] }, - "2168": { "topicTags": ["hash-table", "string", "counting", "hash-function", "rolling-hash"] }, - "2169": { "topicTags": ["math", "simulation"] }, - "2170": { "topicTags": ["greedy", "array", "hash-table", "counting"] }, - "2171": { "topicTags": ["array", "prefix-sum", "sorting"] }, - "2172": { "topicTags": ["bit-manipulation", "array", "dynamic-programming", "bitmask"] }, - "2173": { "topicTags": ["database"] }, - "2174": { "topicTags": ["bit-manipulation", "breadth-first-search", "array", "matrix"] }, - "2175": { "topicTags": ["database"] }, - "2176": { "topicTags": ["array"] }, - "2177": { "topicTags": ["math", "simulation"] }, - "2178": { "topicTags": ["greedy", "math", "backtracking"] }, - "2179": { "topicTags": ["binary-indexed-tree", "segment-tree", "array", "binary-search", "divide-and-conquer", "ordered-set", "merge-sort"] }, - "2180": { "topicTags": ["math", "simulation"] }, - "2181": { "topicTags": ["linked-list", "simulation"] }, - "2182": { "topicTags": ["greedy", "string", "counting", "heap-priority-queue"] }, - "2183": { "topicTags": ["array", "math", "number-theory"] }, - "2184": { "topicTags": ["bit-manipulation", "array", "dynamic-programming", "bitmask"] }, - "2185": { "topicTags": ["array", "string"] }, - "2186": { "topicTags": ["hash-table", "string", "counting"] }, - "2187": { "topicTags": ["array", "binary-search"] }, - "2188": { "topicTags": ["array", "dynamic-programming"] }, - "2189": { "topicTags": ["math", "dynamic-programming"] }, - "2190": { "topicTags": ["array", "hash-table", "counting"] }, - "2191": { "topicTags": ["array", "sorting"] }, - "2192": { "topicTags": ["depth-first-search", "breadth-first-search", "graph", "topological-sort"] }, - "2193": { "topicTags": ["greedy", "binary-indexed-tree", "two-pointers", "string"] }, - "2194": { "topicTags": ["string"] }, - "2195": { "topicTags": ["greedy", "array", "math", "sorting"] }, - "2196": { "topicTags": ["tree", "depth-first-search", "breadth-first-search", "array", "hash-table", "binary-tree"] }, - "2197": { "topicTags": ["stack", "array", "math", "number-theory"] }, - "2198": { "topicTags": ["math"] }, - "2199": { "topicTags": ["database"] }, - "2200": { "topicTags": ["array"] }, - "2201": { "topicTags": ["array", "hash-table", "simulation"] }, - "2202": { "topicTags": ["greedy", "array"] }, - "2203": { "topicTags": ["graph", "shortest-path"] }, - "2204": { "topicTags": ["depth-first-search", "breadth-first-search", "union-find", "graph"] }, - "2205": { "topicTags": ["database"] }, - "2206": { "topicTags": ["bit-manipulation", "array", "hash-table", "counting"] }, - "2207": { "topicTags": ["greedy", "string", "prefix-sum"] }, - "2208": { "topicTags": ["greedy", "array", "heap-priority-queue"] }, - "2209": { "topicTags": ["string", "dynamic-programming", "prefix-sum"] }, - "2210": { "topicTags": ["array"] }, - "2211": { "topicTags": ["stack", "string"] }, - "2212": { "topicTags": ["bit-manipulation", "recursion", "array", "enumeration"] }, - "2213": { "topicTags": ["segment-tree", "array", "string", "ordered-set"] }, - "2214": { "topicTags": ["greedy", "array", "prefix-sum"] }, - "2215": { "topicTags": ["array", "hash-table"] }, - "2216": { "topicTags": ["stack", "greedy", "array"] }, - "2217": { "topicTags": ["array", "math"] }, - "2218": { "topicTags": ["array", "dynamic-programming", "prefix-sum"] }, - "2219": { "topicTags": ["array", "prefix-sum"] }, - "2220": { "topicTags": ["bit-manipulation"] }, - "2221": { "topicTags": ["array", "math", "combinatorics", "simulation"] }, - "2222": { "topicTags": ["string", "dynamic-programming", "prefix-sum"] }, - "2223": { "topicTags": ["string", "binary-search", "string-matching", "suffix-array", "hash-function", "rolling-hash"] }, - "2224": { "topicTags": ["greedy", "string"] }, - "2225": { "topicTags": ["array", "hash-table", "counting", "sorting"] }, - "2226": { "topicTags": ["array", "binary-search"] }, - "2227": { "topicTags": ["design", "trie", "array", "hash-table", "string"] }, - "2228": { "topicTags": ["database"] }, - "2229": { "topicTags": ["array"] }, - "2230": { "topicTags": ["database"] }, - "2231": { "topicTags": ["sorting", "heap-priority-queue"] }, - "2232": { "topicTags": ["string", "enumeration"] }, - "2233": { "topicTags": ["greedy", "array", "heap-priority-queue"] }, - "2234": { "topicTags": ["greedy", "array", "two-pointers", "binary-search", "sorting"] }, - "2235": { "topicTags": ["math"] }, - "2236": { "topicTags": ["tree", "binary-tree"] }, - "2237": { "topicTags": ["array", "prefix-sum"] }, - "2238": { "topicTags": ["database"] }, - "2239": { "topicTags": ["array"] }, - "2240": { "topicTags": ["math", "enumeration"] }, - "2241": { "topicTags": ["greedy", "design", "array"] }, - "2242": { "topicTags": ["graph", "array", "enumeration", "sorting"] }, - "2243": { "topicTags": ["string", "simulation"] }, - "2244": { "topicTags": ["greedy", "array", "hash-table", "counting"] }, - "2245": { "topicTags": ["array", "matrix", "prefix-sum"] }, - "2246": { "topicTags": ["tree", "depth-first-search", "graph", "topological-sort", "array", "string"] }, - "2247": { "topicTags": ["bit-manipulation", "graph", "dynamic-programming", "bitmask"] }, - "2248": { "topicTags": ["array", "hash-table", "counting"] }, - "2249": { "topicTags": ["geometry", "array", "hash-table", "math", "enumeration"] }, - "2250": { "topicTags": ["binary-indexed-tree", "array", "binary-search", "sorting"] }, - "2251": { "topicTags": ["array", "hash-table", "binary-search", "ordered-set", "prefix-sum", "sorting"] }, - "2252": { "topicTags": ["database"] }, - "2253": { "topicTags": ["database"] }, - "2254": { "topicTags": ["stack", "design", "hash-table", "ordered-set"] }, - "2255": { "topicTags": ["array", "string"] }, - "2256": { "topicTags": ["array", "prefix-sum"] }, - "2257": { "topicTags": ["array", "matrix", "simulation"] }, - "2258": { "topicTags": ["breadth-first-search", "array", "binary-search", "matrix"] }, - "2259": { "topicTags": ["greedy", "string", "enumeration"] }, - "2260": { "topicTags": ["array", "hash-table", "sliding-window"] }, - "2261": { "topicTags": ["trie", "array", "hash-table", "enumeration", "hash-function", "rolling-hash"] }, - "2262": { "topicTags": ["hash-table", "string", "dynamic-programming"] }, - "2263": { "topicTags": ["greedy", "dynamic-programming"] }, - "2264": { "topicTags": ["string"] }, - "2265": { "topicTags": ["tree", "depth-first-search", "binary-tree"] }, - "2266": { "topicTags": ["hash-table", "math", "string", "dynamic-programming"] }, - "2267": { "topicTags": ["array", "dynamic-programming", "matrix"] }, - "2268": { "topicTags": ["greedy", "array", "string", "counting", "sorting"] }, - "2269": { "topicTags": ["math", "string", "sliding-window"] }, - "2270": { "topicTags": [] }, - "2271": { "topicTags": ["greedy", "array", "binary-search", "prefix-sum", "sorting"] }, - "2272": { "topicTags": ["array", "dynamic-programming"] }, - "2273": { "topicTags": ["array", "hash-table", "string", "sorting"] }, - "2274": { "topicTags": ["array", "sorting"] }, - "2275": { "topicTags": ["bit-manipulation", "array", "hash-table", "counting"] }, - "2276": { "topicTags": ["design", "segment-tree", "ordered-set"] }, - "2277": { "topicTags": ["tree", "depth-first-search", "breadth-first-search", "array"] }, - "2278": { "topicTags": ["string"] }, - "2279": { "topicTags": ["greedy", "array", "sorting"] }, - "2280": { "topicTags": ["geometry", "array", "math", "number-theory", "sorting"] }, - "2281": { "topicTags": ["stack", "array", "prefix-sum", "monotonic-stack"] }, - "2282": { "topicTags": ["stack", "array", "matrix", "monotonic-stack"] }, - "2283": { "topicTags": ["hash-table", "string", "counting"] }, - "2284": { "topicTags": ["array", "hash-table", "string", "counting"] }, - "2285": { "topicTags": ["greedy", "graph", "sorting", "heap-priority-queue"] }, - "2286": { "topicTags": ["design", "binary-indexed-tree", "segment-tree", "binary-search"] }, - "2287": { "topicTags": ["hash-table", "string", "counting"] }, - "2288": { "topicTags": ["string"] }, - "2289": { "topicTags": ["stack", "array", "linked-list", "monotonic-stack"] }, - "2290": { "topicTags": ["breadth-first-search", "graph", "array", "matrix", "shortest-path", "heap-priority-queue"] }, - "2291": { "topicTags": ["array", "dynamic-programming"] }, - "2292": { "topicTags": ["database"] }, - "2293": { "topicTags": ["array", "simulation"] }, - "2294": { "topicTags": ["greedy", "array", "sorting"] }, - "2295": { "topicTags": ["array", "hash-table", "simulation"] }, - "2296": { "topicTags": ["stack", "design", "linked-list", "string", "doubly-linked-list", "simulation"] }, - "2297": { "topicTags": ["stack", "graph", "array", "dynamic-programming", "shortest-path", "monotonic-stack"] }, - "2298": { "topicTags": ["database"] }, - "2299": { "topicTags": ["string"] }, - "2300": { "topicTags": ["array", "two-pointers", "binary-search", "sorting"] }, - "2301": { "topicTags": ["array", "hash-table", "string", "string-matching"] }, - "2302": { "topicTags": ["array", "binary-search", "prefix-sum", "sliding-window"] }, - "2303": { "topicTags": ["array", "simulation"] }, - "2304": { "topicTags": ["array", "dynamic-programming", "matrix"] }, - "2305": { "topicTags": ["bit-manipulation", "array", "dynamic-programming", "backtracking", "bitmask"] }, - "2306": { "topicTags": ["bit-manipulation", "array", "hash-table", "string", "enumeration"] }, - "2307": { "topicTags": ["depth-first-search", "union-find", "graph", "array"] }, - "2308": { "topicTags": ["database"] }, - "2309": { "topicTags": ["hash-table", "string", "enumeration"] }, - "2310": { "topicTags": ["greedy", "math", "dynamic-programming", "enumeration"] }, - "2311": { "topicTags": ["greedy", "memoization", "string", "dynamic-programming"] }, - "2312": { "topicTags": ["memoization", "array", "dynamic-programming"] }, - "2313": { "topicTags": ["tree", "depth-first-search", "dynamic-programming", "binary-tree"] }, - "2314": { "topicTags": ["database"] }, - "2315": { "topicTags": ["string"] }, - "2316": { "topicTags": ["depth-first-search", "breadth-first-search", "union-find", "graph"] }, - "2317": { "topicTags": ["bit-manipulation", "array", "math"] }, - "2318": { "topicTags": ["memoization", "dynamic-programming"] }, - "2319": { "topicTags": ["array", "matrix"] }, - "2320": { "topicTags": ["dynamic-programming"] }, - "2321": { "topicTags": ["array", "dynamic-programming"] }, - "2322": { "topicTags": ["bit-manipulation", "tree", "depth-first-search", "array"] }, - "2323": { "topicTags": ["greedy", "array", "sorting"] }, - "2324": { "topicTags": ["database"] }, - "2325": { "topicTags": ["hash-table", "string"] }, - "2326": { "topicTags": ["array", "linked-list", "matrix", "simulation"] }, - "2327": { "topicTags": ["queue", "dynamic-programming", "simulation"] }, - "2328": { "topicTags": ["depth-first-search", "breadth-first-search", "graph", "topological-sort", "memoization", "array", "dynamic-programming", "matrix"] }, - "2329": { "topicTags": ["database"] }, - "2330": { "topicTags": ["two-pointers", "string"] }, - "2331": { "topicTags": ["tree", "depth-first-search", "binary-search"] }, - "2332": { "topicTags": ["array", "two-pointers", "binary-search", "sorting"] }, - "2333": { "topicTags": ["array", "math", "sorting", "heap-priority-queue"] }, - "2334": { "topicTags": ["stack", "union-find", "array", "monotonic-stack"] }, - "2335": { "topicTags": ["greedy", "array", "heap-priority-queue"] }, - "2336": { "topicTags": ["design", "hash-table", "heap-priority-queue"] }, - "2337": { "topicTags": ["two-pointers", "string"] }, - "2338": { "topicTags": ["math", "dynamic-programming", "combinatorics", "number-theory"] }, - "2339": { "topicTags": ["database"] }, - "2340": { "topicTags": ["greedy", "array"] }, - "2341": { "topicTags": ["array", "hash-table", "counting"] }, - "2342": { "topicTags": ["array", "hash-table", "sorting", "heap-priority-queue"] }, - "2343": { "topicTags": ["array", "string", "divide-and-conquer", "quickselect", "radix-sort", "sorting", "heap-priority-queue"] }, - "2344": { "topicTags": ["array", "math", "number-theory", "sorting", "heap-priority-queue"] }, - "2345": { "topicTags": ["stack", "array", "sorting", "monotonic-stack"] }, - "2346": { "topicTags": ["database"] }, - "2347": { "topicTags": ["array", "hash-table", "counting"] }, - "2348": { "topicTags": ["array", "math"] }, - "2349": { "topicTags": ["design", "hash-table", "ordered-set", "heap-priority-queue"] }, - "2350": { "topicTags": ["greedy", "array", "hash-table"] }, - "2351": { "topicTags": ["hash-table", "string", "counting"] }, - "2352": { "topicTags": ["array", "hash-table", "matrix", "simulation"] }, - "2353": { "topicTags": ["design", "hash-table", "ordered-set", "heap-priority-queue"] }, - "2354": { "topicTags": ["bit-manipulation", "array", "hash-table", "binary-search"] }, - "2355": { "topicTags": ["stack", "array", "dynamic-programming", "monotonic-stack"] }, - "2356": { "topicTags": ["database"] }, - "2357": { "topicTags": ["array", "hash-table", "sorting", "simulation", "heap-priority-queue"] }, - "2358": { "topicTags": ["greedy", "array", "math", "binary-search"] }, - "2359": { "topicTags": ["depth-first-search", "graph"] }, - "2360": { "topicTags": ["depth-first-search", "graph", "topological-sort"] }, - "2361": { "topicTags": ["array", "dynamic-programming"] }, - "2362": { "topicTags": ["database"] }, - "2363": { "topicTags": ["array", "hash-table", "ordered-set", "sorting"] }, - "2364": { "topicTags": ["array", "hash-table"] }, - "2365": { "topicTags": ["array", "hash-table", "simulation"] }, - "2366": { "topicTags": ["greedy", "array", "math"] }, - "2367": { "topicTags": ["array", "hash-table", "two-pointers", "enumeration"] }, - "2368": { "topicTags": ["tree", "depth-first-search", "breadth-first-search", "graph", "array", "hash-table"] }, - "2369": { "topicTags": ["array", "dynamic-programming"] }, - "2370": { "topicTags": ["hash-table", "string", "dynamic-programming"] }, - "2371": { "topicTags": ["greedy", "union-find", "graph", "topological-sort", "array", "matrix", "sorting"] }, - "2372": { "topicTags": ["database"] }, - "2373": { "topicTags": ["array", "matrix"] }, - "2374": { "topicTags": ["graph", "hash-table"] }, - "2375": { "topicTags": ["stack", "greedy", "string", "backtracking"] }, - "2376": { "topicTags": ["math", "dynamic-programming"] }, - "2377": { "topicTags": ["database"] }, - "2378": { "topicTags": ["tree", "depth-first-search", "dynamic-programming"] }, - "2379": { "topicTags": ["string", "sliding-window"] }, - "2380": { "topicTags": ["string", "dynamic-programming", "simulation"] }, - "2381": { "topicTags": ["array", "string", "prefix-sum"] }, - "2382": { "topicTags": ["union-find", "array", "ordered-set", "prefix-sum"] }, - "2383": { "topicTags": ["greedy", "array"] }, - "2384": { "topicTags": ["greedy", "hash-table", "string"] }, - "2385": { "topicTags": ["tree", "depth-first-search", "breadth-first-search", "binary-tree"] }, - "2386": { "topicTags": ["array", "sorting", "heap-priority-queue"] }, - "2387": { "topicTags": ["array", "binary-search", "matrix"] }, - "2388": { "topicTags": ["database"] }, - "2389": { "topicTags": ["greedy", "array", "binary-search", "prefix-sum", "sorting"] }, - "2390": { "topicTags": ["stack", "string", "simulation"] }, - "2391": { "topicTags": ["array", "string", "prefix-sum"] }, - "2392": { "topicTags": ["graph", "topological-sort", "array", "matrix"] }, - "2393": { "topicTags": ["array", "math", "dynamic-programming"] }, - "2394": { "topicTags": ["database"] }, - "2395": { "topicTags": ["array", "hash-table"] }, - "2396": { "topicTags": ["brainteaser", "math", "two-pointers"] }, - "2397": { "topicTags": ["bit-manipulation", "array", "backtracking", "enumeration", "matrix"] }, - "2398": { "topicTags": ["queue", "array", "binary-search", "prefix-sum", "sliding-window", "heap-priority-queue"] }, - "2399": { "topicTags": ["array", "hash-table", "string"] }, - "2400": { "topicTags": ["math", "dynamic-programming", "combinatorics"] }, - "2401": { "topicTags": ["bit-manipulation", "array", "sliding-window"] }, - "2402": { "topicTags": ["array", "sorting", "heap-priority-queue"] }, - "2403": { "topicTags": ["bit-manipulation", "array", "dynamic-programming", "bitmask"] }, - "2404": { "topicTags": ["array", "hash-table", "counting"] }, - "2405": { "topicTags": ["greedy", "hash-table", "string"] }, - "2406": { "topicTags": ["greedy", "array", "two-pointers", "prefix-sum", "sorting", "heap-priority-queue"] }, - "2407": { "topicTags": ["binary-indexed-tree", "segment-tree", "queue", "array", "divide-and-conquer", "dynamic-programming", "monotonic-queue"] }, - "2408": { "topicTags": ["design", "array", "hash-table", "string"] }, - "2409": { "topicTags": ["math", "string"] }, - "2410": { "topicTags": ["greedy", "array", "two-pointers", "sorting"] }, - "2411": { "topicTags": ["bit-manipulation", "array", "binary-search", "sliding-window"] }, - "2412": { "topicTags": ["greedy", "array", "sorting"] }, - "2413": { "topicTags": ["math", "number-theory"] }, - "2414": { "topicTags": ["string"] }, - "2415": { "topicTags": ["tree", "depth-first-search", "breadth-first-search", "binary-tree"] }, - "2416": { "topicTags": ["trie", "array", "string", "counting"] }, - "2417": { "topicTags": ["math", "enumeration"] }, - "2418": { "topicTags": ["array", "hash-table", "string", "sorting"] }, - "2419": { "topicTags": ["bit-manipulation", "brainteaser", "array"] }, - "2420": { "topicTags": ["array", "dynamic-programming", "prefix-sum"] }, - "2421": { "topicTags": ["tree", "union-find", "graph", "array"] }, - "LCP 01": { "topicTags": ["array"] }, - "LCP 02": { "topicTags": ["array", "math", "number-theory", "simulation"] }, - "LCP 03": { "topicTags": ["array", "hash-table", "simulation"] }, - "LCP 04": { "topicTags": ["bit-manipulation", "graph", "array", "dynamic-programming", "bitmask"] }, - "LCP 05": { "topicTags": ["binary-indexed-tree", "segment-tree", "array"] }, - "LCP 06": { "topicTags": ["array", "math"] }, - "LCP 07": { "topicTags": ["depth-first-search", "breadth-first-search", "graph", "dynamic-programming"] }, - "LCP 08": { "topicTags": ["array", "binary-search", "sorting"] }, - "LCP 09": { "topicTags": ["breadth-first-search", "segment-tree", "array", "dynamic-programming"] }, - "LCP 10": { "topicTags": ["tree", "depth-first-search", "dynamic-programming", "binary-tree"] }, - "LCP 11": { "topicTags": ["array", "hash-table", "math", "probability-and-statistics"] }, - "LCP 12": { "topicTags": ["array", "binary-search"] }, - "LCP 13": { "topicTags": ["bit-manipulation", "breadth-first-search", "array", "dynamic-programming", "bitmask", "matrix"] }, - "LCP 14": { "topicTags": ["array", "math", "dynamic-programming", "number-theory"] }, - "LCP 15": { "topicTags": ["greedy", "geometry", "array", "math"] }, - "LCP 16": { "topicTags": ["graph", "geometry", "math"] }, - "LCP 17": { "topicTags": ["math", "string", "simulation"] }, - "LCP 18": { "topicTags": ["array", "two-pointers", "binary-search", "sorting"] }, - "LCP 19": { "topicTags": ["string", "dynamic-programming"] }, - "LCP 20": { "topicTags": ["memoization", "array", "dynamic-programming"] }, - "LCP 21": { "topicTags": ["depth-first-search", "breadth-first-search", "graph", "topological-sort"] }, - "LCP 22": { "topicTags": ["math"] }, - "LCP 23": { "topicTags": ["queue", "array", "simulation"] }, - "LCP 24": { "topicTags": ["array", "math", "heap-priority-queue"] }, - "LCP 25": { "topicTags": ["math", "dynamic-programming", "combinatorics"] }, - "LCP 26": { "topicTags": ["tree", "dynamic-programming", "binary-tree"] }, - "LCP 27": { "topicTags": ["design", "segment-tree", "math", "ordered-set"] }, - "LCP 28": { "topicTags": ["array", "two-pointers", "binary-search", "sorting"] }, - "LCP 29": { "topicTags": ["math"] }, - "LCP 30": { "topicTags": ["greedy", "array", "heap-priority-queue"] }, - "LCP 31": { "topicTags": ["depth-first-search", "breadth-first-search", "array", "dynamic-programming", "matrix"] }, - "LCP 32": { "topicTags": ["greedy", "array", "heap-priority-queue"] }, - "LCP 33": { "topicTags": ["greedy", "array", "heap-priority-queue"] }, - "LCP 34": { "topicTags": ["tree", "dynamic-programming", "binary-tree"] }, - "LCP 35": { "topicTags": ["graph", "shortest-path", "heap-priority-queue"] }, - "LCP 36": { "topicTags": ["array", "dynamic-programming", "sorting"] }, - "LCP 37": { "topicTags": ["greedy", "geometry", "array", "math", "combinatorics", "sorting"] }, - "LCP 38": { "topicTags": ["array", "dynamic-programming", "matrix"] }, - "LCP 39": { "topicTags": ["array", "hash-table", "counting", "matrix"] }, - "LCP 40": { "topicTags": ["greedy", "array", "sorting"] }, - "LCP 41": { "topicTags": ["breadth-first-search", "array", "matrix"] }, - "LCP 42": { "topicTags": ["geometry", "array", "hash-table", "math", "binary-search", "sorting"] }, - "LCP 43": { "topicTags": ["array", "string", "dynamic-programming"] }, - "LCP 44": { "topicTags": ["tree", "depth-first-search", "breadth-first-search", "hash-table", "binary-tree"] }, - "LCP 45": { "topicTags": ["depth-first-search", "breadth-first-search", "memoization", "array", "dynamic-programming", "matrix"] }, - "LCP 46": { "topicTags": ["graph", "array", "math"] }, - "LCP 47": { "topicTags": ["array", "dynamic-programming"] }, - "LCP 48": { "topicTags": ["array", "math", "enumeration", "game-theory"] }, - "LCP 49": { "topicTags": ["bit-manipulation", "union-find", "array", "heap-priority-queue"] }, - "LCP 50": { "topicTags": ["array", "simulation"] }, - "LCP 51": { "topicTags": ["bit-manipulation", "array", "backtracking", "enumeration"] }, - "LCP 52": { "topicTags": ["tree", "segment-tree", "binary-search-tree", "array", "binary-search", "binary-tree", "ordered-set"] }, - "LCP 53": { "topicTags": ["bit-manipulation", "array", "dynamic-programming", "bitmask"] }, - "LCP 54": { "topicTags": ["graph", "array", "biconnected-component"] }, - "LCP 55": { "topicTags": ["array"] }, - "LCP 56": { "topicTags": ["breadth-first-search", "graph", "array", "matrix", "shortest-path", "heap-priority-queue"] }, - "LCP 57": { "topicTags": ["array", "dynamic-programming", "matrix", "sorting"] }, - "LCP 58": { "topicTags": ["array", "backtracking", "matrix"] }, - "LCP 59": { "topicTags": ["array", "dynamic-programming"] }, - "LCP 60": { "topicTags": ["tree", "dynamic-programming", "binary-tree"] }, - "LCP 61": { "topicTags": [] }, - "LCP 62": { "topicTags": [] }, - "LCP 63": { "topicTags": [] }, - "LCP 64": { "topicTags": [] }, - "LCP 65": { "topicTags": [] }, - "LCS 01": { "topicTags": ["greedy", "math", "dynamic-programming"] }, - "LCS 02": { "topicTags": ["greedy", "array", "hash-table", "sorting"] }, - "LCS 03": { "topicTags": ["depth-first-search", "breadth-first-search", "union-find", "array", "matrix"] }, - "剑指 Offer 03": { "topicTags": ["array", "hash-table", "sorting"] }, - "剑指 Offer 04": { "topicTags": ["array", "binary-search", "divide-and-conquer", "matrix"] }, - "剑指 Offer 05": { "topicTags": ["string"] }, - "剑指 Offer 06": { "topicTags": ["stack", "recursion", "linked-list", "two-pointers"] }, - "剑指 Offer 07": { "topicTags": ["tree", "array", "hash-table", "divide-and-conquer", "binary-tree"] }, - "剑指 Offer 09": { "topicTags": ["stack", "design", "queue"] }, - "剑指 Offer 10- I": { "topicTags": ["memoization", "math", "dynamic-programming"] }, - "剑指 Offer 10- II": { "topicTags": ["memoization", "math", "dynamic-programming"] }, - "剑指 Offer 11": { "topicTags": ["array", "binary-search"] }, - "剑指 Offer 12": { "topicTags": ["array", "backtracking", "matrix"] }, - "剑指 Offer 14- I": { "topicTags": ["math", "dynamic-programming"] }, - "剑指 Offer 14- II": { "topicTags": ["math", "dynamic-programming"] }, - "剑指 Offer 15": { "topicTags": ["bit-manipulation"] }, - "剑指 Offer 16": { "topicTags": ["recursion", "math"] }, - "剑指 Offer 17": { "topicTags": ["array", "math"] }, - "剑指 Offer 18": { "topicTags": ["linked-list"] }, - "剑指 Offer 19": { "topicTags": ["recursion", "string", "dynamic-programming"] }, - "剑指 Offer 20": { "topicTags": ["string"] }, - "剑指 Offer 21": { "topicTags": ["array", "two-pointers", "sorting"] }, - "剑指 Offer 22": { "topicTags": ["linked-list", "two-pointers"] }, - "剑指 Offer 24": { "topicTags": ["recursion", "linked-list"] }, - "剑指 Offer 25": { "topicTags": ["recursion", "linked-list"] }, - "剑指 Offer 26": { "topicTags": ["tree", "depth-first-search", "binary-tree"] }, - "剑指 Offer 27": { "topicTags": ["tree", "depth-first-search", "breadth-first-search", "binary-tree"] }, - "剑指 Offer 28": { "topicTags": ["tree", "depth-first-search", "breadth-first-search", "binary-tree"] }, - "剑指 Offer 29": { "topicTags": ["array", "matrix", "simulation"] }, - "剑指 Offer 30": { "topicTags": ["stack", "design"] }, - "剑指 Offer 31": { "topicTags": ["stack", "array", "simulation"] }, - "剑指 Offer 32 - I": { "topicTags": ["tree", "breadth-first-search", "binary-tree"] }, - "剑指 Offer 32 - II": { "topicTags": ["tree", "breadth-first-search", "binary-tree"] }, - "剑指 Offer 32 - III": { "topicTags": ["tree", "breadth-first-search", "binary-tree"] }, - "剑指 Offer 33": { "topicTags": ["stack", "tree", "binary-search-tree", "recursion", "binary-tree", "monotonic-stack"] }, - "剑指 Offer 34": { "topicTags": ["tree", "depth-first-search", "backtracking", "binary-tree"] }, - "剑指 Offer 35": { "topicTags": ["hash-table", "linked-list"] }, - "剑指 Offer 36": { "topicTags": ["stack", "tree", "depth-first-search", "binary-search-tree", "linked-list", "binary-tree", "doubly-linked-list"] }, - "剑指 Offer 37": { "topicTags": ["tree", "depth-first-search", "breadth-first-search", "design", "string", "binary-tree"] }, - "剑指 Offer 38": { "topicTags": ["string", "backtracking"] }, - "剑指 Offer 39": { "topicTags": ["array", "hash-table", "divide-and-conquer", "counting", "sorting"] }, - "剑指 Offer 40": { "topicTags": ["array", "divide-and-conquer", "quickselect", "sorting", "heap-priority-queue"] }, - "剑指 Offer 41": { "topicTags": ["design", "two-pointers", "data-stream", "sorting", "heap-priority-queue"] }, - "剑指 Offer 42": { "topicTags": ["array", "divide-and-conquer", "dynamic-programming"] }, - "剑指 Offer 43": { "topicTags": ["recursion", "math", "dynamic-programming"] }, - "剑指 Offer 44": { "topicTags": ["math", "binary-search"] }, - "剑指 Offer 45": { "topicTags": ["greedy", "string", "sorting"] }, - "剑指 Offer 46": { "topicTags": ["string", "dynamic-programming"] }, - "剑指 Offer 47": { "topicTags": ["array", "dynamic-programming", "matrix"] }, - "剑指 Offer 48": { "topicTags": ["hash-table", "string", "sliding-window"] }, - "剑指 Offer 49": { "topicTags": ["hash-table", "math", "dynamic-programming", "heap-priority-queue"] }, - "剑指 Offer 50": { "topicTags": ["queue", "hash-table", "string", "counting"] }, - "剑指 Offer 51": { "topicTags": ["binary-indexed-tree", "segment-tree", "array", "binary-search", "divide-and-conquer", "ordered-set", "merge-sort"] }, - "剑指 Offer 52": { "topicTags": ["hash-table", "linked-list", "two-pointers"] }, - "剑指 Offer 53 - I": { "topicTags": ["array", "binary-search"] }, - "剑指 Offer 53 - II": { "topicTags": ["bit-manipulation", "array", "hash-table", "math", "binary-search"] }, - "剑指 Offer 54": { "topicTags": ["tree", "depth-first-search", "binary-search-tree", "binary-tree"] }, - "剑指 Offer 55 - I": { "topicTags": ["tree", "depth-first-search", "breadth-first-search", "binary-tree"] }, - "剑指 Offer 55 - II": { "topicTags": ["tree", "depth-first-search", "binary-tree"] }, - "剑指 Offer 56 - I": { "topicTags": ["bit-manipulation", "array"] }, - "剑指 Offer 56 - II": { "topicTags": ["bit-manipulation", "array"] }, - "剑指 Offer 57": { "topicTags": ["array", "two-pointers", "binary-search"] }, - "剑指 Offer 57 - II": { "topicTags": ["math", "two-pointers", "enumeration"] }, - "剑指 Offer 58 - I": { "topicTags": ["two-pointers", "string"] }, - "剑指 Offer 58 - II": { "topicTags": ["math", "two-pointers", "string"] }, - "剑指 Offer 59 - I": { "topicTags": ["queue", "sliding-window", "monotonic-queue", "heap-priority-queue"] }, - "剑指 Offer 60": { "topicTags": ["math", "dynamic-programming", "probability-and-statistics"] }, - "剑指 Offer 61": { "topicTags": ["array", "sorting"] }, - "剑指 Offer 62": { "topicTags": ["recursion", "math"] }, - "剑指 Offer 63": { "topicTags": ["array", "dynamic-programming"] }, - "剑指 Offer 64": { "topicTags": ["bit-manipulation", "recursion", "brainteaser"] }, - "剑指 Offer 65": { "topicTags": ["bit-manipulation", "math"] }, - "剑指 Offer 66": { "topicTags": ["array", "prefix-sum"] }, - "剑指 Offer 67": { "topicTags": ["string"] }, - "剑指 Offer 68 - I": { "topicTags": ["tree", "depth-first-search", "binary-search-tree", "binary-tree"] }, - "剑指 Offer 68 - II": { "topicTags": ["tree", "depth-first-search", "binary-tree"] }, - "剑指 Offer II 001": { "topicTags": ["bit-manipulation", "math"] }, - "剑指 Offer II 002": { "topicTags": ["bit-manipulation", "math", "string", "simulation"] }, - "剑指 Offer II 003": { "topicTags": ["bit-manipulation", "dynamic-programming"] }, - "剑指 Offer II 004": { "topicTags": ["bit-manipulation", "array"] }, - "剑指 Offer II 005": { "topicTags": ["bit-manipulation", "array", "string"] }, - "剑指 Offer II 006": { "topicTags": ["array", "two-pointers", "binary-search"] }, - "剑指 Offer II 007": { "topicTags": ["array", "two-pointers", "sorting"] }, - "剑指 Offer II 008": { "topicTags": ["array", "binary-search", "prefix-sum", "sliding-window"] }, - "剑指 Offer II 009": { "topicTags": ["array", "sliding-window"] }, - "剑指 Offer II 010": { "topicTags": ["array", "hash-table", "prefix-sum"] }, - "剑指 Offer II 011": { "topicTags": ["array", "hash-table", "prefix-sum"] }, - "剑指 Offer II 012": { "topicTags": ["array", "prefix-sum"] }, - "剑指 Offer II 013": { "topicTags": ["design", "array", "matrix", "prefix-sum"] }, - "剑指 Offer II 014": { "topicTags": ["hash-table", "two-pointers", "string", "sliding-window"] }, - "剑指 Offer II 015": { "topicTags": ["hash-table", "string", "sliding-window"] }, - "剑指 Offer II 016": { "topicTags": ["hash-table", "string", "sliding-window"] }, - "剑指 Offer II 017": { "topicTags": ["hash-table", "string", "sliding-window"] }, - "剑指 Offer II 018": { "topicTags": ["two-pointers", "string"] }, - "剑指 Offer II 019": { "topicTags": ["greedy", "two-pointers", "string"] }, - "剑指 Offer II 020": { "topicTags": ["string", "dynamic-programming"] }, - "剑指 Offer II 021": { "topicTags": ["linked-list", "two-pointers"] }, - "剑指 Offer II 022": { "topicTags": ["hash-table", "linked-list", "two-pointers"] }, - "剑指 Offer II 023": { "topicTags": ["hash-table", "linked-list", "two-pointers"] }, - "剑指 Offer II 024": { "topicTags": ["recursion", "linked-list"] }, - "剑指 Offer II 025": { "topicTags": ["stack", "linked-list", "math"] }, - "剑指 Offer II 026": { "topicTags": ["stack", "recursion", "linked-list", "two-pointers"] }, - "剑指 Offer II 027": { "topicTags": ["stack", "recursion", "linked-list", "two-pointers"] }, - "剑指 Offer II 028": { "topicTags": ["depth-first-search", "linked-list", "doubly-linked-list"] }, - "剑指 Offer II 029": { "topicTags": ["linked-list"] }, - "剑指 Offer II 030": { "topicTags": ["design", "array", "hash-table", "math", "randomized"] }, - "剑指 Offer II 031": { "topicTags": ["design", "hash-table", "linked-list", "doubly-linked-list"] }, - "剑指 Offer II 032": { "topicTags": ["hash-table", "string", "sorting"] }, - "剑指 Offer II 033": { "topicTags": ["array", "hash-table", "string", "sorting"] }, - "剑指 Offer II 034": { "topicTags": ["array", "hash-table", "string"] }, - "剑指 Offer II 035": { "topicTags": ["array", "math", "string", "sorting"] }, - "剑指 Offer II 036": { "topicTags": ["stack", "array", "math"] }, - "剑指 Offer II 037": { "topicTags": ["stack", "array"] }, - "剑指 Offer II 038": { "topicTags": ["stack", "array", "monotonic-stack"] }, - "剑指 Offer II 039": { "topicTags": ["stack", "array", "monotonic-stack"] }, - "剑指 Offer II 040": { "topicTags": ["stack", "array", "dynamic-programming", "matrix", "monotonic-stack"] }, - "剑指 Offer II 041": { "topicTags": ["design", "queue", "array", "data-stream"] }, - "剑指 Offer II 042": { "topicTags": ["design", "queue", "data-stream"] }, - "剑指 Offer II 043": { "topicTags": ["tree", "breadth-first-search", "design", "binary-tree"] }, - "剑指 Offer II 044": { "topicTags": ["tree", "depth-first-search", "breadth-first-search", "binary-tree"] }, - "剑指 Offer II 045": { "topicTags": ["tree", "depth-first-search", "breadth-first-search", "binary-tree"] }, - "剑指 Offer II 046": { "topicTags": ["tree", "depth-first-search", "breadth-first-search", "binary-tree"] }, - "剑指 Offer II 047": { "topicTags": ["tree", "depth-first-search", "binary-tree"] }, - "剑指 Offer II 048": { "topicTags": ["tree", "depth-first-search", "breadth-first-search", "design", "string", "binary-tree"] }, - "剑指 Offer II 049": { "topicTags": ["tree", "depth-first-search", "binary-tree"] }, - "剑指 Offer II 050": { "topicTags": ["tree", "depth-first-search", "binary-tree"] }, - "剑指 Offer II 051": { "topicTags": ["tree", "depth-first-search", "dynamic-programming", "binary-tree"] }, - "剑指 Offer II 052": { "topicTags": ["stack", "tree", "depth-first-search", "binary-search-tree", "binary-tree"] }, - "剑指 Offer II 053": { "topicTags": ["tree", "depth-first-search", "binary-search-tree", "binary-tree"] }, - "剑指 Offer II 054": { "topicTags": ["tree", "depth-first-search", "binary-search-tree", "binary-tree"] }, - "剑指 Offer II 055": { "topicTags": ["stack", "tree", "design", "binary-search-tree", "binary-tree", "iterator"] }, - "剑指 Offer II 056": { "topicTags": ["tree", "depth-first-search", "breadth-first-search", "binary-search-tree", "hash-table", "two-pointers", "binary-tree"] }, - "剑指 Offer II 057": { "topicTags": ["array", "bucket-sort", "ordered-set", "sorting", "sliding-window"] }, - "剑指 Offer II 058": { "topicTags": ["design", "segment-tree", "binary-search", "ordered-set"] }, - "剑指 Offer II 059": { "topicTags": ["tree", "design", "binary-search-tree", "binary-tree", "data-stream", "heap-priority-queue"] }, - "剑指 Offer II 060": { "topicTags": ["array", "hash-table", "divide-and-conquer", "bucket-sort", "counting", "quickselect", "sorting", "heap-priority-queue"] }, - "剑指 Offer II 061": { "topicTags": ["array", "heap-priority-queue"] }, - "剑指 Offer II 062": { "topicTags": ["design", "trie", "hash-table", "string"] }, - "剑指 Offer II 063": { "topicTags": ["trie", "array", "hash-table", "string"] }, - "剑指 Offer II 064": { "topicTags": ["design", "trie", "hash-table", "string"] }, - "剑指 Offer II 065": { "topicTags": ["trie", "array", "hash-table", "string"] }, - "剑指 Offer II 066": { "topicTags": ["design", "trie", "hash-table", "string"] }, - "剑指 Offer II 067": { "topicTags": ["bit-manipulation", "trie", "array", "hash-table"] }, - "剑指 Offer II 068": { "topicTags": ["array", "binary-search"] }, - "剑指 Offer II 069": { "topicTags": ["array", "binary-search"] }, - "剑指 Offer II 070": { "topicTags": ["array", "binary-search"] }, - "剑指 Offer II 071": { "topicTags": ["math", "binary-search", "prefix-sum", "randomized"] }, - "剑指 Offer II 072": { "topicTags": ["math", "binary-search"] }, - "剑指 Offer II 073": { "topicTags": ["array", "binary-search"] }, - "剑指 Offer II 074": { "topicTags": ["array", "sorting"] }, - "剑指 Offer II 075": { "topicTags": ["array", "hash-table", "counting-sort", "sorting"] }, - "剑指 Offer II 076": { "topicTags": ["array", "divide-and-conquer", "quickselect", "sorting", "heap-priority-queue"] }, - "剑指 Offer II 077": { "topicTags": ["linked-list", "two-pointers", "divide-and-conquer", "sorting", "merge-sort"] }, - "剑指 Offer II 078": { "topicTags": ["linked-list", "divide-and-conquer", "heap-priority-queue", "merge-sort"] }, - "剑指 Offer II 079": { "topicTags": ["bit-manipulation", "array", "backtracking"] }, - "剑指 Offer II 080": { "topicTags": ["array", "backtracking"] }, - "剑指 Offer II 081": { "topicTags": ["array", "backtracking"] }, - "剑指 Offer II 082": { "topicTags": ["array", "backtracking"] }, - "剑指 Offer II 083": { "topicTags": ["array", "backtracking"] }, - "剑指 Offer II 084": { "topicTags": ["array", "backtracking"] }, - "剑指 Offer II 085": { "topicTags": ["string", "dynamic-programming", "backtracking"] }, - "剑指 Offer II 086": { "topicTags": ["depth-first-search", "breadth-first-search", "graph", "hash-table"] }, - "剑指 Offer II 087": { "topicTags": ["string", "backtracking"] }, - "剑指 Offer II 088": { "topicTags": ["array", "dynamic-programming"] }, - "剑指 Offer II 089": { "topicTags": ["array", "dynamic-programming"] }, - "剑指 Offer II 090": { "topicTags": ["array", "dynamic-programming"] }, - "剑指 Offer II 091": { "topicTags": ["array", "dynamic-programming"] }, - "剑指 Offer II 092": { "topicTags": ["string", "dynamic-programming"] }, - "剑指 Offer II 093": { "topicTags": ["array", "hash-table", "dynamic-programming"] }, - "剑指 Offer II 094": { "topicTags": ["string", "dynamic-programming"] }, - "剑指 Offer II 095": { "topicTags": ["string", "dynamic-programming"] }, - "剑指 Offer II 096": { "topicTags": ["string", "dynamic-programming"] }, - "剑指 Offer II 097": { "topicTags": ["string", "dynamic-programming"] }, - "剑指 Offer II 098": { "topicTags": ["math", "dynamic-programming", "combinatorics"] }, - "剑指 Offer II 099": { "topicTags": ["array", "dynamic-programming", "matrix"] }, - "剑指 Offer II 100": { "topicTags": ["array", "dynamic-programming"] }, - "剑指 Offer II 101": { "topicTags": ["math", "string", "simulation"] }, - "剑指 Offer II 102": { "topicTags": ["array", "dynamic-programming", "backtracking"] }, - "剑指 Offer II 103": { "topicTags": ["breadth-first-search", "array", "dynamic-programming"] }, - "剑指 Offer II 104": { "topicTags": ["array", "dynamic-programming"] }, - "剑指 Offer II 105": { "topicTags": ["depth-first-search", "breadth-first-search", "union-find", "array", "matrix"] }, - "剑指 Offer II 106": { "topicTags": ["depth-first-search", "breadth-first-search", "union-find", "graph"] }, - "剑指 Offer II 107": { "topicTags": ["breadth-first-search", "array", "dynamic-programming", "matrix"] }, - "剑指 Offer II 108": { "topicTags": ["breadth-first-search", "hash-table", "string"] }, - "剑指 Offer II 109": { "topicTags": ["breadth-first-search", "array", "hash-table", "string"] }, - "剑指 Offer II 110": { "topicTags": ["depth-first-search", "breadth-first-search", "graph", "backtracking"] }, - "剑指 Offer II 111": { "topicTags": ["depth-first-search", "breadth-first-search", "union-find", "graph", "array", "shortest-path"] }, - "剑指 Offer II 112": { "topicTags": ["depth-first-search", "breadth-first-search", "graph", "topological-sort", "memoization", "array", "dynamic-programming", "matrix"] }, - "剑指 Offer II 113": { "topicTags": ["depth-first-search", "breadth-first-search", "graph", "topological-sort"] }, - "剑指 Offer II 114": { "topicTags": ["depth-first-search", "breadth-first-search", "graph", "topological-sort", "array", "string"] }, - "剑指 Offer II 115": { "topicTags": ["graph", "topological-sort", "array"] }, - "剑指 Offer II 116": { "topicTags": ["depth-first-search", "breadth-first-search", "union-find", "graph"] }, - "剑指 Offer II 117": { "topicTags": ["depth-first-search", "breadth-first-search", "union-find", "array", "string"] }, - "剑指 Offer II 118": { "topicTags": ["depth-first-search", "breadth-first-search", "union-find", "graph"] }, - "剑指 Offer II 119": { "topicTags": ["union-find", "array", "hash-table"] }, - "面试题 01.01": { "topicTags": ["bit-manipulation", "hash-table", "string", "sorting"] }, - "面试题 01.02": { "topicTags": ["hash-table", "string", "sorting"] }, - "面试题 01.03": { "topicTags": ["string"] }, - "面试题 01.04": { "topicTags": ["bit-manipulation", "hash-table", "string"] }, - "面试题 01.05": { "topicTags": ["two-pointers", "string"] }, - "面试题 01.06": { "topicTags": ["two-pointers", "string"] }, - "面试题 01.07": { "topicTags": ["array", "math", "matrix"] }, - "面试题 01.08": { "topicTags": ["array", "hash-table", "matrix"] }, - "面试题 01.09": { "topicTags": ["string", "string-matching"] }, - "面试题 02.01": { "topicTags": ["hash-table", "linked-list", "two-pointers"] }, - "面试题 02.02": { "topicTags": ["linked-list", "two-pointers"] }, - "面试题 02.03": { "topicTags": ["linked-list"] }, - "面试题 02.04": { "topicTags": ["linked-list", "two-pointers"] }, - "面试题 02.05": { "topicTags": ["recursion", "linked-list", "math"] }, - "面试题 02.06": { "topicTags": ["stack", "recursion", "linked-list", "two-pointers"] }, - "面试题 02.07": { "topicTags": ["hash-table", "linked-list", "two-pointers"] }, - "面试题 02.08": { "topicTags": ["hash-table", "linked-list", "two-pointers"] }, - "面试题 03.01": { "topicTags": ["stack", "design", "array"] }, - "面试题 03.02": { "topicTags": ["stack", "design"] }, - "面试题 03.03": { "topicTags": ["stack", "design", "linked-list"] }, - "面试题 03.04": { "topicTags": ["stack", "design", "queue"] }, - "面试题 03.05": { "topicTags": ["stack", "design", "monotonic-stack"] }, - "面试题 03.06": { "topicTags": ["design", "queue"] }, - "面试题 04.01": { "topicTags": ["depth-first-search", "breadth-first-search", "union-find", "graph"] }, - "面试题 04.02": { "topicTags": ["tree", "binary-search-tree", "array", "divide-and-conquer", "binary-tree"] }, - "面试题 04.03": { "topicTags": ["tree", "breadth-first-search", "linked-list", "binary-tree"] }, - "面试题 04.04": { "topicTags": ["tree", "depth-first-search", "binary-tree"] }, - "面试题 04.05": { "topicTags": ["tree", "depth-first-search", "binary-search-tree", "binary-tree"] }, - "面试题 04.06": { "topicTags": ["tree", "depth-first-search", "binary-search-tree", "binary-tree"] }, - "面试题 04.08": { "topicTags": ["tree", "depth-first-search", "binary-tree"] }, - "面试题 04.09": { "topicTags": ["tree", "binary-search-tree", "backtracking", "binary-tree"] }, - "面试题 04.10": { "topicTags": ["tree", "depth-first-search", "binary-tree", "string-matching", "hash-function"] }, - "面试题 04.12": { "topicTags": ["tree", "depth-first-search", "binary-tree"] }, - "面试题 05.01": { "topicTags": ["bit-manipulation"] }, - "面试题 05.02": { "topicTags": ["bit-manipulation", "math", "string"] }, - "面试题 05.03": { "topicTags": ["bit-manipulation", "dynamic-programming"] }, - "面试题 05.04": { "topicTags": ["bit-manipulation"] }, - "面试题 05.06": { "topicTags": ["bit-manipulation"] }, - "面试题 05.07": { "topicTags": ["bit-manipulation"] }, - "面试题 05.08": { "topicTags": ["bit-manipulation", "array", "math"] }, - "面试题 08.01": { "topicTags": ["memoization", "math", "dynamic-programming"] }, - "面试题 08.02": { "topicTags": ["array", "dynamic-programming", "backtracking", "matrix"] }, - "面试题 08.03": { "topicTags": ["array", "binary-search"] }, - "面试题 08.04": { "topicTags": ["bit-manipulation", "array", "backtracking"] }, - "面试题 08.05": { "topicTags": ["bit-manipulation", "recursion", "math"] }, - "面试题 08.06": { "topicTags": ["recursion", "array"] }, - "面试题 08.07": { "topicTags": ["string", "backtracking"] }, - "面试题 08.08": { "topicTags": ["string", "backtracking"] }, - "面试题 08.09": { "topicTags": ["string", "dynamic-programming", "backtracking"] }, - "面试题 08.10": { "topicTags": ["depth-first-search", "breadth-first-search", "array", "matrix"] }, - "面试题 08.11": { "topicTags": ["array", "math", "dynamic-programming"] }, - "面试题 08.12": { "topicTags": ["array", "backtracking"] }, - "面试题 08.13": { "topicTags": ["array", "dynamic-programming", "sorting"] }, - "面试题 08.14": { "topicTags": ["memoization", "string", "dynamic-programming"] }, - "面试题 10.01": { "topicTags": ["array", "two-pointers", "sorting"] }, - "面试题 10.02": { "topicTags": ["array", "hash-table", "string", "sorting"] }, - "面试题 10.03": { "topicTags": ["array", "binary-search"] }, - "面试题 10.05": { "topicTags": ["array", "string", "binary-search"] }, - "面试题 10.09": { "topicTags": ["array", "binary-search", "divide-and-conquer", "matrix"] }, - "面试题 10.10": { "topicTags": ["design", "binary-indexed-tree", "binary-search", "data-stream"] }, - "面试题 10.11": { "topicTags": ["greedy", "array", "sorting"] }, - "面试题 16.01": { "topicTags": ["bit-manipulation", "math"] }, - "面试题 16.02": { "topicTags": ["design", "trie", "array", "hash-table", "string"] }, - "面试题 16.03": { "topicTags": ["geometry", "math"] }, - "面试题 16.04": { "topicTags": ["array", "counting", "matrix"] }, - "面试题 16.05": { "topicTags": ["math"] }, - "面试题 16.06": { "topicTags": ["array", "two-pointers", "binary-search", "sorting"] }, - "面试题 16.07": { "topicTags": ["bit-manipulation", "brainteaser", "math"] }, - "面试题 16.08": { "topicTags": ["recursion", "math", "string"] }, - "面试题 16.09": { "topicTags": ["design", "math"] }, - "面试题 16.10": { "topicTags": ["array", "counting"] }, - "面试题 16.11": { "topicTags": ["array", "math"] }, - "面试题 16.13": { "topicTags": ["geometry", "math"] }, - "面试题 16.14": { "topicTags": ["geometry", "array", "hash-table", "math"] }, - "面试题 16.15": { "topicTags": ["hash-table", "string", "counting"] }, - "面试题 16.16": { "topicTags": ["stack", "greedy", "array", "two-pointers", "sorting", "monotonic-stack"] }, - "面试题 16.17": { "topicTags": ["array", "divide-and-conquer", "dynamic-programming"] }, - "面试题 16.18": { "topicTags": ["math", "string", "backtracking", "enumeration"] }, - "面试题 16.19": { "topicTags": ["depth-first-search", "breadth-first-search", "union-find", "array", "matrix"] }, - "面试题 16.20": { "topicTags": ["array", "hash-table", "string"] }, - "面试题 16.21": { "topicTags": ["array", "hash-table", "binary-search", "sorting"] }, - "面试题 16.22": { "topicTags": ["array", "hash-table", "string", "matrix", "simulation"] }, - "面试题 16.24": { "topicTags": ["array", "hash-table", "two-pointers", "counting", "sorting"] }, - "面试题 16.25": { "topicTags": ["design", "hash-table", "linked-list", "doubly-linked-list"] }, - "面试题 16.26": { "topicTags": ["stack", "math", "string"] }, - "面试题 17.01": { "topicTags": ["bit-manipulation", "math"] }, - "面试题 17.04": { "topicTags": ["bit-manipulation", "array", "hash-table", "math", "sorting"] }, - "面试题 17.05": { "topicTags": ["array", "hash-table", "prefix-sum"] }, - "面试题 17.06": { "topicTags": ["recursion", "math", "dynamic-programming"] }, - "面试题 17.07": { "topicTags": ["depth-first-search", "breadth-first-search", "union-find", "array", "hash-table", "string", "counting"] }, - "面试题 17.08": { "topicTags": ["array", "binary-search", "dynamic-programming", "sorting"] }, - "面试题 17.09": { "topicTags": ["hash-table", "math", "dynamic-programming", "heap-priority-queue"] }, - "面试题 17.10": { "topicTags": ["array", "counting"] }, - "面试题 17.11": { "topicTags": ["array", "string"] }, - "面试题 17.12": { "topicTags": ["stack", "tree", "depth-first-search", "binary-search-tree", "linked-list", "binary-tree"] }, - "面试题 17.13": { "topicTags": ["trie", "array", "hash-table", "string", "dynamic-programming", "hash-function", "rolling-hash"] }, - "面试题 17.14": { "topicTags": ["array", "divide-and-conquer", "quickselect", "sorting", "heap-priority-queue"] }, - "面试题 17.15": { "topicTags": ["trie", "array", "hash-table", "string"] }, - "面试题 17.16": { "topicTags": ["array", "dynamic-programming"] }, - "面试题 17.17": { "topicTags": ["trie", "array", "hash-table", "string", "string-matching", "sliding-window"] }, - "面试题 17.18": { "topicTags": ["array", "hash-table", "sliding-window"] }, - "面试题 17.19": { "topicTags": ["bit-manipulation", "array", "hash-table"] }, - "面试题 17.20": { "topicTags": ["design", "two-pointers", "data-stream", "sorting", "heap-priority-queue"] }, - "面试题 17.21": { "topicTags": ["stack", "array", "two-pointers", "dynamic-programming", "monotonic-stack"] }, - "面试题 17.22": { "topicTags": ["breadth-first-search", "hash-table", "string", "backtracking"] }, - "面试题 17.23": { "topicTags": ["array", "dynamic-programming", "matrix"] }, - "面试题 17.24": { "topicTags": ["array", "dynamic-programming", "matrix", "prefix-sum"] }, - "面试题 17.25": { "topicTags": ["trie", "array", "string", "backtracking"] }, - "面试题 17.26": { "topicTags": ["array", "hash-table", "sorting"] }, - "面试题13": { "topicTags": ["depth-first-search", "breadth-first-search", "dynamic-programming"] }, - "面试题59 - II": { "topicTags": ["design", "queue", "monotonic-queue"] } - }; - - private tags_name = { - 'array': '数组', - 'hash-table': '哈希表', - 'recursion': '递归', - 'linked-list': '链表', - 'math': '数学', - 'string': '字符串', - 'sliding-window': '滑动窗口', - 'binary-search': '二分搜索', - 'divide-and-conquer': '分治', - 'dynamic-programming': '动态规划', - 'greedy': '贪心', - 'two-pointers': '双指针', - 'sorting': '排序', - 'backtracking': '回溯', - 'stack': '堆', - 'heap-priority-queue': '优先级队列', - 'merge-sort': '归并排序', - 'string-matching': '字符串匹配', - 'bit-manipulation': '位操作', - 'matrix': '矩阵', - 'monotonic-stack': '单调栈', - 'simulation': '模拟', - 'combinatorics': '组合学', - 'memoization': '记忆', - 'tree': '树', - 'depth-first-search': '深度优先搜索', - 'binary-tree': '二叉树', - 'binary-search-tree': '二叉搜索树', - 'breadth-first-search': '广度优先搜索', - 'union-find': '并查集', - 'graph': '图', - 'trie': '尝试', - 'design': '设计', - 'doubly-linked-list': '双向链表', - 'geometry': '几何学', - 'interactive': '交互的', - 'bucket-sort': '桶排序', - 'radix-sort': '基数排序', - 'counting': '数数', - 'data-stream': '数据流', - 'iterator': '迭代器', - 'database': '数据库', - 'hash-function': '散列函数', - 'rolling-hash': '滚动哈希', - 'shell': '脚本', - 'enumeration': '枚举', - 'number-theory': '数论', - 'topological-sort': '拓扑排序', - 'prefix-sum': '前缀和', - 'quickselect': '快速选择', - 'binary-indexed-tree': '二进制索引树', - 'segment-tree': '线段树', - 'ordered-set': '有序集', - 'line-sweep': '扫描线', - 'queue': '队列', - 'monotonic-queue': '单调队列', - 'counting-sort': '计数排序', - 'brainteaser': '脑筋急转弯', - 'game-theory': '博弈论', - 'eulerian-circuit': '欧拉回路', - 'randomized': '随机', - 'reservoir-sampling': '水库采样', - 'shortest-path': '最短路径', - 'bitmask': '位掩码', - 'rejection-sampling': '拒绝抽样', - 'probability-and-statistics': '概率和统计', - 'suffix-array': '后缀数组', - 'concurrency': '并发', - 'minimum-spanning-tree': '最小生成树', - 'biconnected-component': '双连接组件', - 'strongly-connected-component': '强连接组件' - - }; - public getTagsData(fid: string): Array { - return (this.tagsData[fid]?.topicTags || []).map(p => { - return this.tags_name[p]; - }); - } - + private tags_name = { + array: "数组", + "hash-table": "哈希表", + recursion: "递归", + "linked-list": "链表", + math: "数学", + string: "字符串", + "sliding-window": "滑动窗口", + "binary-search": "二分搜索", + "divide-and-conquer": "分治", + "dynamic-programming": "动态规划", + greedy: "贪心", + "two-pointers": "双指针", + sorting: "排序", + backtracking: "回溯", + stack: "堆", + "heap-priority-queue": "优先级队列", + "merge-sort": "归并排序", + "string-matching": "字符串匹配", + "bit-manipulation": "位操作", + matrix: "矩阵", + "monotonic-stack": "单调栈", + simulation: "模拟", + combinatorics: "组合学", + memoization: "记忆", + tree: "树", + "depth-first-search": "深度优先搜索", + "binary-tree": "二叉树", + "binary-search-tree": "二叉搜索树", + "breadth-first-search": "广度优先搜索", + "union-find": "并查集", + graph: "图", + trie: "尝试", + design: "设计", + "doubly-linked-list": "双向链表", + geometry: "几何学", + interactive: "交互的", + "bucket-sort": "桶排序", + "radix-sort": "基数排序", + counting: "数数", + "data-stream": "数据流", + iterator: "迭代器", + database: "数据库", + "hash-function": "散列函数", + "rolling-hash": "滚动哈希", + shell: "脚本", + enumeration: "枚举", + "number-theory": "数论", + "topological-sort": "拓扑排序", + "prefix-sum": "前缀和", + quickselect: "快速选择", + "binary-indexed-tree": "二进制索引树", + "segment-tree": "线段树", + "ordered-set": "有序集", + "line-sweep": "扫描线", + queue: "队列", + "monotonic-queue": "单调队列", + "counting-sort": "计数排序", + brainteaser: "脑筋急转弯", + "game-theory": "博弈论", + "eulerian-circuit": "欧拉回路", + randomized: "随机", + "reservoir-sampling": "水库采样", + "shortest-path": "最短路径", + bitmask: "位掩码", + "rejection-sampling": "拒绝抽样", + "probability-and-statistics": "概率和统计", + "suffix-array": "后缀数组", + concurrency: "并发", + "minimum-spanning-tree": "最小生成树", + "biconnected-component": "双连接组件", + "strongly-connected-component": "强连接组件", + }; + public getTagsData(fid: string): Array { + return (this.tagsData[fid]?.topicTags || []).map((p) => { + return this.tags_name[p]; + }); + } } - export const tagsDao: TagsDao = new TagsDao(); - - - - - - diff --git a/src/extension.ts b/src/extension.ts index 5ddec09..7b11ec2 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -7,7 +7,6 @@ * Copyright (c) 2022 ccagml . All rights reserved. */ - import { ExtensionContext, window, commands, Uri } from "vscode"; import { fileButtonController } from "./controller/FileButtonController"; import { treeViewController } from "./controller/TreeViewController"; @@ -29,63 +28,75 @@ import { DialogType } from "./model/Model"; // 激活插件 export async function activate(context: ExtensionContext): Promise { - try { - - // 初始化控制器 - mainContorller.initialize(context); - // 检查node环境 - await mainContorller.checkNodeEnv(context); - // 事件监听 - eventController.add_event(); + try { + // 初始化控制器 + mainContorller.initialize(context); + // 检查node环境 + await mainContorller.checkNodeEnv(context); + // 事件监听 + eventController.add_event(); - // 资源管理 - context.subscriptions.push( - statusBarService, - logOutput, - previewService, - submissionService, - solutionService, - executeService, - markdownService, - fileButtonController, - treeViewController, - window.registerFileDecorationProvider(treeItemDecorationService), - window.createTreeView("leetCodeExplorer", { treeDataProvider: treeDataService, showCollapseAll: true }), - commands.registerCommand("leetcode.deleteCache", () => mainContorller.deleteCache()), - commands.registerCommand("leetcode.toggleLeetCodeCn", () => treeViewController.switchEndpoint()), - commands.registerCommand("leetcode.signin", () => loginContorller.signIn()), - commands.registerCommand("leetcode.signout", () => loginContorller.signOut()), - commands.registerCommand("leetcode.previewProblem", (node: NodeModel) => treeViewController.previewProblem(node)), - commands.registerCommand("leetcode.showProblem", (node: NodeModel) => treeViewController.showProblem(node)), - commands.registerCommand("leetcode.pickOne", () => treeViewController.pickOne()), - commands.registerCommand("leetcode.deleteAllCache", () => loginContorller.deleteAllCache()), - commands.registerCommand("leetcode.searchScoreRange", () => treeViewController.searchScoreRange()), - commands.registerCommand("leetcode.searchProblem", () => treeViewController.searchProblem()), - commands.registerCommand("leetcode.showSolution", (input: NodeModel | Uri) => treeViewController.showSolution(input)), - commands.registerCommand("leetcode.refreshExplorer", () => treeDataService.refresh()), - commands.registerCommand("leetcode.testSolution", (uri?: Uri) => treeViewController.testSolution(uri)), - commands.registerCommand("leetcode.testSolutionDefault", (uri?: Uri, allCase?: boolean) => treeViewController.testSolutionDefault(uri, allCase)), - commands.registerCommand("leetcode.submitSolution", (uri?: Uri) => treeViewController.submitSolution(uri)), - commands.registerCommand("leetcode.switchDefaultLanguage", () => treeViewController.switchDefaultLanguage()), - commands.registerCommand("leetcode.addFavorite", (node: NodeModel) => treeViewController.addFavorite(node)), - commands.registerCommand("leetcode.removeFavorite", (node: NodeModel) => treeViewController.removeFavorite(node)), - commands.registerCommand("leetcode.problems.sort", () => treeViewController.switchSortingStrategy()), - ); + // 资源管理 + context.subscriptions.push( + statusBarService, + logOutput, + previewService, + submissionService, + solutionService, + executeService, + markdownService, + fileButtonController, + treeViewController, + window.registerFileDecorationProvider(treeItemDecorationService), + window.createTreeView("leetCodeExplorer", { + treeDataProvider: treeDataService, + showCollapseAll: true, + }), + commands.registerCommand("leetcode.deleteCache", () => mainContorller.deleteCache()), + commands.registerCommand("leetcode.toggleLeetCodeCn", () => treeViewController.switchEndpoint()), + commands.registerCommand("leetcode.signin", () => loginContorller.signIn()), + commands.registerCommand("leetcode.signout", () => loginContorller.signOut()), + commands.registerCommand("leetcode.previewProblem", (node: NodeModel) => treeViewController.previewProblem(node)), + commands.registerCommand("leetcode.showProblem", (node: NodeModel) => treeViewController.showProblem(node)), + commands.registerCommand("leetcode.pickOne", () => treeViewController.pickOne()), + commands.registerCommand("leetcode.deleteAllCache", () => loginContorller.deleteAllCache()), + commands.registerCommand("leetcode.searchScoreRange", () => treeViewController.searchScoreRange()), + commands.registerCommand("leetcode.searchProblem", () => treeViewController.searchProblem()), + commands.registerCommand("leetcode.showSolution", (input: NodeModel | Uri) => + treeViewController.showSolution(input) + ), + commands.registerCommand("leetcode.refreshExplorer", () => treeDataService.refresh()), + commands.registerCommand("leetcode.testSolution", (uri?: Uri) => treeViewController.testSolution(uri)), + commands.registerCommand("leetcode.testSolutionDefault", (uri?: Uri, allCase?: boolean) => + treeViewController.testSolutionDefault(uri, allCase) + ), + commands.registerCommand("leetcode.testSolutionArea", (uri?: Uri, testCase?: string) => + treeViewController.testSolutionArea(uri, testCase) + ), + commands.registerCommand("leetcode.submitSolution", (uri?: Uri) => treeViewController.submitSolution(uri)), + commands.registerCommand("leetcode.switchDefaultLanguage", () => treeViewController.switchDefaultLanguage()), + commands.registerCommand("leetcode.addFavorite", (node: NodeModel) => treeViewController.addFavorite(node)), + commands.registerCommand("leetcode.removeFavorite", (node: NodeModel) => treeViewController.removeFavorite(node)), + commands.registerCommand("leetcode.problems.sort", () => treeViewController.switchSortingStrategy()) + ); - // 设置站点 - await executeService.switchEndpoint(getLeetCodeEndpoint()); - // 获取登录状态 - await loginContorller.getLoginStatus(); - } catch (error) { - logOutput.appendLine(error.toString()); - promptForOpenOutputChannel("Extension initialization failed. Please open output channel for details.", DialogType.error); - } + // 设置站点 + await executeService.switchEndpoint(getLeetCodeEndpoint()); + // 获取登录状态 + await loginContorller.getLoginStatus(); + } catch (error) { + logOutput.appendLine(error.toString()); + promptForOpenOutputChannel( + "Extension initialization failed. Please open output channel for details.", + DialogType.error + ); + } } export function deactivate(): void { - // Do nothing. - if (0) { - let a = 0; - console.log(a); - } + // Do nothing. + if (0) { + let a = 0; + console.log(a); + } } diff --git a/src/model/Model.ts b/src/model/Model.ts index 170dea0..6e775df 100644 --- a/src/model/Model.ts +++ b/src/model/Model.ts @@ -7,277 +7,269 @@ * Copyright (c) 2022 ccagml . All rights reserved. */ - import { ViewColumn, QuickPickItem, MessageItem } from "vscode"; export interface IQuickItemEx extends QuickPickItem { - value: T; + value: T; } export enum UserStatus { - SignedIn = 1, - SignedOut = 2, + SignedIn = 1, + SignedOut = 2, } export const loginArgsMapping: Map = new Map([ - ["LeetCode", "-l"], - ["Cookie", "-c"], - ["GitHub", "-g"], - ["LinkedIn", "-i"], + ["LeetCode", "-l"], + ["Cookie", "-c"], + ["GitHub", "-g"], + ["LinkedIn", "-i"], ]); export const languages: string[] = [ - "bash", - "c", - "cpp", - "csharp", - "golang", - "java", - "javascript", - "kotlin", - "mysql", - "php", - "python", - "python3", - "ruby", - "rust", - "scala", - "swift", - "typescript", + "bash", + "c", + "cpp", + "csharp", + "golang", + "java", + "javascript", + "kotlin", + "mysql", + "php", + "python", + "python3", + "ruby", + "rust", + "scala", + "swift", + "typescript", ]; export const langExt: Map = new Map([ - ["bash", "sh"], - ["c", "c"], - ["cpp", "cpp"], - ["csharp", "cs"], - ["golang", "go"], - ["java", "java"], - ["javascript", "js"], - ["kotlin", "kt"], - ["mysql", "sql"], - ["php", "php"], - ["python", "py"], - ["python3", "py"], - ["ruby", "rb"], - ["rust", "rs"], - ["scala", "scala"], - ["swift", "swift"], - ["typescript", "ts"], + ["bash", "sh"], + ["c", "c"], + ["cpp", "cpp"], + ["csharp", "cs"], + ["golang", "go"], + ["java", "java"], + ["javascript", "js"], + ["kotlin", "kt"], + ["mysql", "sql"], + ["php", "php"], + ["python", "py"], + ["python3", "py"], + ["ruby", "rb"], + ["rust", "rs"], + ["scala", "scala"], + ["swift", "swift"], + ["typescript", "ts"], ]); export enum ProblemState { - AC = 1, - NotAC = 2, - Unknown = 3, + AC = 1, + NotAC = 2, + Unknown = 3, } export enum Endpoint { - LeetCode = "leetcode", - LeetCodeCN = "leetcode-cn", + LeetCode = "leetcode", + LeetCodeCN = "leetcode-cn", } export enum RootNodeSort { - ZERO = 0, - Day = 1, - All = 2, - Difficulty = 3, - Tag = 4, - Company = 5, - Favorite = 6, - Choice = 7, - Score = 8, - ScoreRange = 9, - Context = 9, + ZERO = 0, + Day = 1, + All = 2, + Difficulty = 3, + Tag = 4, + Company = 5, + Favorite = 6, + Choice = 7, + Score = 8, + ScoreRange = 9, + Context = 9, } - export interface IProblem { - isFavorite: boolean; - locked: boolean; - state: ProblemState; - id: string; // 题目编号 fid - qid: string; - name: string; - difficulty: string; - passRate: string; - companies: string[]; - tags: string[]; - scoreData: IScoreData | undefined; // 分数的结构 - isSearchResult: boolean; - input: string; - rootNodeSortId: RootNodeSort; - todayData: ITodayData | undefined; + isFavorite: boolean; + locked: boolean; + state: ProblemState; + id: string; // 题目编号 fid + qid: string; + name: string; + difficulty: string; + passRate: string; + companies: string[]; + tags: string[]; + scoreData: IScoreData | undefined; // 分数的结构 + isSearchResult: boolean; + input: string; + rootNodeSortId: RootNodeSort; + todayData: ITodayData | undefined; } export interface ITodayData { - date: string; // 日期 - userStatus: string; // 状态 'NOT_START' 'FINISH' + date: string; // 日期 + userStatus: string; // 状态 'NOT_START' 'FINISH' } - export interface IScoreData { - Rating: number; // 分数 - score: string; // rank分 - ID: number; // 题目ID - ContestID_en: string; // 周赛名称 - ProblemIndex: string; // 周赛第几题 - ContestSlug: string; // 周赛名称 + Rating: number; // 分数 + score: string; // rank分 + ID: number; // 题目ID + ContestID_en: string; // 周赛名称 + ProblemIndex: string; // 周赛第几题 + ContestSlug: string; // 周赛名称 } export const defaultProblem: IProblem = { - isFavorite: false, - locked: false, - state: ProblemState.Unknown, - id: "", - qid: "", - name: "", - difficulty: "", - passRate: "", - companies: [] as string[], - tags: [] as string[], - scoreData: undefined, - isSearchResult: false, - input: "", - rootNodeSortId: RootNodeSort.ZERO, - todayData: undefined + isFavorite: false, + locked: false, + state: ProblemState.Unknown, + id: "", + qid: "", + name: "", + difficulty: "", + passRate: "", + companies: [] as string[], + tags: [] as string[], + scoreData: undefined, + isSearchResult: false, + input: "", + rootNodeSortId: RootNodeSort.ZERO, + todayData: undefined, }; export enum Category { - All = "All", - Difficulty = "Difficulty", - Tag = "Tag", - Company = "Company", - Favorite = "Favorite", - Score = "Score", - Choice = "Choice", - + All = "All", + Difficulty = "Difficulty", + Tag = "Tag", + Company = "Company", + Favorite = "Favorite", + Score = "Score", + Choice = "Choice", } export const supportedPlugins: string[] = [ - // "company", - "solution.discuss", - "leetcode.cn", + // "company", + "solution.discuss", + "leetcode.cn", ]; export enum DescriptionConfiguration { - InWebView = "In Webview", - InFileComment = "In File Comment", - Both = "Both", - None = "None", + InWebView = "In Webview", + InFileComment = "In File Comment", + Both = "Both", + None = "None", } export const leetcodeHasInited: string = "leetcode.hasInited"; export enum SortingStrategy { - None = "None", - AcceptanceRateAsc = "Acceptance Rate (Ascending)", - AcceptanceRateDesc = "Acceptance Rate (Descending)", - FrequencyAsc = "Frequency (Ascending)", - FrequencyDesc = "Frequency (Descending)", - ScoreAsc = "Score (Ascending)", - ScoreDesc = "Score (Descending)", - IDDesc = "ID (Descending)" + None = "None", + AcceptanceRateAsc = "Acceptance Rate (Ascending)", + AcceptanceRateDesc = "Acceptance Rate (Descending)", + FrequencyAsc = "Frequency (Ascending)", + FrequencyDesc = "Frequency (Descending)", + ScoreAsc = "Score (Ascending)", + ScoreDesc = "Score (Descending)", + IDDesc = "ID (Descending)", } - export const SORT_ORDER: SortingStrategy[] = [ - SortingStrategy.None, - SortingStrategy.AcceptanceRateAsc, - SortingStrategy.AcceptanceRateDesc, - SortingStrategy.ScoreAsc, - SortingStrategy.ScoreDesc, - SortingStrategy.IDDesc, + SortingStrategy.None, + SortingStrategy.AcceptanceRateAsc, + SortingStrategy.AcceptanceRateDesc, + SortingStrategy.ScoreAsc, + SortingStrategy.ScoreDesc, + SortingStrategy.IDDesc, ]; - export enum SearchSetType { - ScoreRange = "ScoreRange", - Context = "Context", - Day = "Day", + ScoreRange = "ScoreRange", + Context = "Context", + Day = "Day", } export enum SearchSetTypeName { - ScoreRange = "分数范围:", - Context = "周赛期数:", - Day = "每日一题" + ScoreRange = "分数范围:", + Context = "周赛期数:", + Day = "每日一题", } export interface ISearchSet { - value: string, - type: SearchSetType, - time: number, // 时间戳 - todayData: ITodayData | undefined; + value: string; + type: SearchSetType; + time: number; // 时间戳 + todayData: ITodayData | undefined; } export const SearchNode: ISearchSet = { - value: "", - type: SearchSetType.ScoreRange, - time: 0, - todayData: undefined + value: "", + type: SearchSetType.ScoreRange, + time: 0, + todayData: undefined, }; export interface userContestRanKingBase { - attendedContestsCount: number, // 参与次数 - rating: number, // 分数 - globalRanking: number, // 全球名次 - localRanking: number, // 本地名次 - globalTotalParticipants: number, //全球所有 - localTotalParticipants: number, // 本地所有 - topPercentage: number, // 位次百分比 + attendedContestsCount: number; // 参与次数 + rating: number; // 分数 + globalRanking: number; // 全球名次 + localRanking: number; // 本地名次 + globalTotalParticipants: number; //全球所有 + localTotalParticipants: number; // 本地所有 + topPercentage: number; // 位次百分比 } export const userContestRankingObj: userContestRanKingBase = { - attendedContestsCount: 0, - rating: 1500, - globalRanking: 0, - localRanking: 0, - globalTotalParticipants: 0, - localTotalParticipants: 0, - topPercentage: 0, + attendedContestsCount: 0, + rating: 1500, + globalRanking: 0, + localRanking: 0, + globalTotalParticipants: 0, + localTotalParticipants: 0, + topPercentage: 0, }; - export interface ISubmitEvent { - fid: string; - qid: string; - id: string; - sub_type: string; // test submit - accepted: boolean + fid: string; + qid: string; + id: string; + sub_type: string; // test submit + accepted: boolean; } - export interface IWebViewOption { - title: string; - viewColumn: ViewColumn; - preserveFocus?: boolean; + title: string; + viewColumn: ViewColumn; + preserveFocus?: boolean; } - export enum OpenOption { - justOpenFile = "仅打开问题文件", - openInCurrentWindow = "在当前VsCode窗口打开", - openInNewWindow = "在新的VsCode窗口打开", - addToWorkspace = "添加到工作空间", + justOpenFile = "仅打开问题文件", + openInCurrentWindow = "在当前VsCode窗口打开", + openInNewWindow = "在新的VsCode窗口打开", + addToWorkspace = "添加到工作空间", } export enum DialogType { - info = "info", - warning = "warning", - error = "error", + info = "info", + warning = "warning", + error = "error", } - export const MessageItemObj: MessageItem = { - title: "", - isCloseAffordance: false, + title: "", + isCloseAffordance: false, }; - export const DialogOptions = { - open: Object.assign({}, MessageItemObj, { title: "Open" }), - yes: Object.assign({}, MessageItemObj, { title: "Yes" }), - no: Object.assign({}, MessageItemObj, { title: "No", isCloseAffordance: true }), - never: Object.assign({}, MessageItemObj, { title: "Never" }), - singUp: Object.assign({}, MessageItemObj, { title: "Sign up" }), + open: Object.assign({}, MessageItemObj, { title: "Open" }), + yes: Object.assign({}, MessageItemObj, { title: "Yes" }), + no: Object.assign({}, MessageItemObj, { + title: "No", + isCloseAffordance: true, + }), + never: Object.assign({}, MessageItemObj, { title: "Never" }), + singUp: Object.assign({}, MessageItemObj, { title: "Sign up" }), }; diff --git a/src/model/NodeModel.ts b/src/model/NodeModel.ts index 39c0e52..b1b2448 100644 --- a/src/model/NodeModel.ts +++ b/src/model/NodeModel.ts @@ -7,137 +7,135 @@ * Copyright (c) 2022 ccagml . All rights reserved. */ - import { Command, Uri } from "vscode"; import { IProblem, IScoreData, ITodayData, ProblemState, RootNodeSort } from "./Model"; export class NodeModel { - private _u_score; - constructor(private data: IProblem, private isProblemNode: boolean = true, userscore: number = 0) { - this._u_score = userscore; - } - - public get locked(): boolean { - return this.data.locked; - } - public get name(): string { - return this.data.name; - } - - public get state(): ProblemState { - - // 每日一题的修正 - if (this.todayData) { - const us = this.todayDataUserStatus; - if (us == "FINISH") { - return ProblemState.AC; - } else { - return ProblemState.Unknown; - } - } - - return this.data.state; - } - - public get id(): string { - return this.data.id; - } - - public get passRate(): string { - return this.data.passRate; - } - - public get difficulty(): string { - return this.data.difficulty; - } - - public get tags(): string[] { - return this.data.tags; - } - - public get companies(): string[] { - return this.data.companies; - } - - public get isFavorite(): boolean { - return this.data.isFavorite; - } - - public get isProblem(): boolean { - return this.isProblemNode; - } - public get rootNodeSortId(): RootNodeSort { - return this.data.rootNodeSortId; - } - - public get previewCommand(): Command { - return { - title: "Preview Problem", - command: "leetcode.previewProblem", - arguments: [this], - }; - } - - public get acceptanceRate(): number { - return Number(this.passRate) || 50; - } - - public get uri(): Uri { - return Uri.from({ - scheme: "leetcode", - authority: this.isProblem ? "problems" : "tree-node", - path: `/${this.id}`, // path must begin with slash / - query: `difficulty=${this.difficulty}&score=${this.score}&user_score=${this._u_score}`, - }); - } - - public set set_user_score(s: number) { - this._u_score = s; - } - - public get user_score(): number { - return this._u_score; - } - - // rank分 - public get score(): string { - return this.data.scoreData?.score || "0"; - } - // 周赛名称 - public get ContestID_en(): string { - return this.data.scoreData?.ContestID_en || ""; - } - // 周赛第几题 - public get ProblemIndex(): string { - return this.data.scoreData?.ProblemIndex || ""; - } - // 周赛名称符号链接 - public get ContestSlug(): string { - return this.data.scoreData?.ContestSlug || ""; - } - public get scoreData(): IScoreData | undefined { - return this.data.scoreData; - } - public get isSearchResult(): boolean { - return this.data.isSearchResult; - } - public get input(): string { - return this.data.input || ""; - } - // 每日一题的一些信息 - public get todayData(): ITodayData | undefined { - return this.data.todayData; - } - public set todayData(s: ITodayData | undefined) { - this.data.todayData = s; - } - public get todayDataDate(): string { - return this.data.todayData?.date || ""; - } - public get todayDataUserStatus(): string { - return this.data.todayData?.userStatus || ""; - } - public get qid(): string { - return this.data.qid || ""; - } + private _u_score; + constructor(private data: IProblem, private isProblemNode: boolean = true, userscore: number = 0) { + this._u_score = userscore; + } + + public get locked(): boolean { + return this.data.locked; + } + public get name(): string { + return this.data.name; + } + + public get state(): ProblemState { + // 每日一题的修正 + if (this.todayData) { + const us = this.todayDataUserStatus; + if (us == "FINISH") { + return ProblemState.AC; + } else { + return ProblemState.Unknown; + } + } + + return this.data.state; + } + + public get id(): string { + return this.data.id; + } + + public get passRate(): string { + return this.data.passRate; + } + + public get difficulty(): string { + return this.data.difficulty; + } + + public get tags(): string[] { + return this.data.tags; + } + + public get companies(): string[] { + return this.data.companies; + } + + public get isFavorite(): boolean { + return this.data.isFavorite; + } + + public get isProblem(): boolean { + return this.isProblemNode; + } + public get rootNodeSortId(): RootNodeSort { + return this.data.rootNodeSortId; + } + + public get previewCommand(): Command { + return { + title: "Preview Problem", + command: "leetcode.previewProblem", + arguments: [this], + }; + } + + public get acceptanceRate(): number { + return Number(this.passRate) || 50; + } + + public get uri(): Uri { + return Uri.from({ + scheme: "leetcode", + authority: this.isProblem ? "problems" : "tree-node", + path: `/${this.id}`, // path must begin with slash / + query: `difficulty=${this.difficulty}&score=${this.score}&user_score=${this._u_score}`, + }); + } + + public set set_user_score(s: number) { + this._u_score = s; + } + + public get user_score(): number { + return this._u_score; + } + + // rank分 + public get score(): string { + return this.data.scoreData?.score || "0"; + } + // 周赛名称 + public get ContestID_en(): string { + return this.data.scoreData?.ContestID_en || ""; + } + // 周赛第几题 + public get ProblemIndex(): string { + return this.data.scoreData?.ProblemIndex || ""; + } + // 周赛名称符号链接 + public get ContestSlug(): string { + return this.data.scoreData?.ContestSlug || ""; + } + public get scoreData(): IScoreData | undefined { + return this.data.scoreData; + } + public get isSearchResult(): boolean { + return this.data.isSearchResult; + } + public get input(): string { + return this.data.input || ""; + } + // 每日一题的一些信息 + public get todayData(): ITodayData | undefined { + return this.data.todayData; + } + public set todayData(s: ITodayData | undefined) { + this.data.todayData = s; + } + public get todayDataDate(): string { + return this.data.todayData?.date || ""; + } + public get todayDataUserStatus(): string { + return this.data.todayData?.userStatus || ""; + } + public get qid(): string { + return this.data.qid || ""; + } } diff --git a/src/rpc/actionChain/chainManager.ts b/src/rpc/actionChain/chainManager.ts new file mode 100644 index 0000000..2c0c833 --- /dev/null +++ b/src/rpc/actionChain/chainManager.ts @@ -0,0 +1,82 @@ +/* + * Filename: /home/cc/vscode-leetcode-problem-rating/src/rpc/actionChain/chainMgr.ts + * Path: /home/cc/vscode-leetcode-problem-rating + * Created Date: Monday, November 14th 2022, 4:04:31 pm + * Author: ccagml + * + * Copyright (c) 2022 ccagml . All rights reserved. + */ + +let underscore = require("underscore"); + +import { storageUtils } from "../utils/storageUtils"; +import { commUtils } from "../utils/commUtils"; +import { ChainNodeBase } from "./chainNodeBase"; + +export class ChainManager { + id; + name; + ver; + desc; + + plugins: Array = []; + installed: Array = []; + head: ChainNodeBase; // 插件头 是core + + constructor() {} + + public getChainHead(): ChainNodeBase { + return this.head; + } + + public init(head: ChainNodeBase | undefined): Object | undefined { + if (head) { + this.head = head; + } + const stats = storageUtils.getCache(commUtils.KEYS.plugins) || {}; + let fileChainNode: Array = storageUtils.listCodeDir("../actionChain/chainNode"); + this.installed = []; + for (let f of fileChainNode) { + const p = f.data; + if (!p) continue; + p.file = f.file; + p.enabled = stats[p.name]; + if (!(p.name in stats)) { + if (p.builtin) { + p.enabled = true; + } else { + p.enabled = false; + } + } + this.installed.push(p); + } + // 根据id大小排序, 大的前面 + this.installed = underscore.sortBy(this.installed, (x) => -x.id); + // 从小的开始init + for (let i = this.installed.length - 1; i >= 0; --i) { + const p = this.installed[i]; + if (p.enabled) { + p.init(); + } + } + // 连成链表状 + this.plugins = this.installed.filter((x) => x.enabled); + let last = head; + if (last) { + for (let p of this.plugins) { + last.setNext(p); + last = p; + } + } + + return true; + } + + public save_all(): void { + for (let p of this.plugins) { + p.save(); + } + } +} + +export const chainMgr: ChainManager = new ChainManager(); diff --git a/src/rpc/actionChain/chainNode/cache.ts b/src/rpc/actionChain/chainNode/cache.ts new file mode 100644 index 0000000..05c40e0 --- /dev/null +++ b/src/rpc/actionChain/chainNode/cache.ts @@ -0,0 +1,127 @@ +/* + * Filename: /home/cc/vscode-leetcode-problem-rating/src/rpc/actionChain/cache.ts + * Path: /home/cc/vscode-leetcode-problem-rating + * Created Date: Monday, November 14th 2022, 4:04:31 pm + * Author: ccagml + * + * Copyright (c) 2022 ccagml . All rights reserved. + */ + +import { ChainNodeBase } from "../chainNodeBase"; + +let underscore = require("underscore"); + +import { storageUtils } from "../../utils/storageUtils"; +import { commUtils } from "../../utils/commUtils"; +import { sessionUtils } from "../../utils/sessionUtils"; + +class CachePlugin extends ChainNodeBase { + id = 50; + name = "cache"; + builtin = true; + constructor() { + super(); + } + + clearCacheIfTchanged = (needTranslation) => { + const translationConfig = storageUtils.getCache(commUtils.KEYS.translation); + if (!translationConfig || translationConfig["useEndpointTranslation"] != needTranslation) { + storageUtils.deleteAllCache(); + storageUtils.setCache(commUtils.KEYS.translation, { + useEndpointTranslation: needTranslation, + }); + } + }; + + public getProblems = (needTranslation, cb) => { + this.clearCacheIfTchanged(needTranslation); + const problems = storageUtils.getCache(commUtils.KEYS.problems); + if (problems) { + return cb(null, problems); + } + this.next.getProblems(needTranslation, function (e, problems) { + if (e) return cb(e); + storageUtils.setCache(commUtils.KEYS.problems, problems); + return cb(null, problems); + }); + }; + + /** + * getRatingOnline + */ + public getRatingOnline = (cb) => { + const cacheRantingData = storageUtils.getCache(commUtils.KEYS.ranting_path); + if (cacheRantingData) { + return cb(null, cacheRantingData); + } + this.next.getRatingOnline(function (e, ratingData) { + if (e) return cb(e); + let ratingObj; + try { + ratingObj = JSON.parse(ratingData); + } catch (error) { + return cb("JSON.parse(ratingData) error"); + } + storageUtils.setCache(commUtils.KEYS.ranting_path, ratingObj); + return cb(null, ratingObj); + }); + }; + + public getProblem = (problem, needTranslation, cb) => { + this.clearCacheIfTchanged(needTranslation); + const k = commUtils.KEYS.problem(problem); + const _problem = storageUtils.getCache(k); + let that = this; + if (_problem) { + if (!_problem.desc.includes(" ")) { + // + } else if (!["likes", "dislikes"].every((p) => p in _problem)) { + // + } else { + underscore.extendOwn(problem, _problem); + return cb(null, problem); + } + } + this.next.getProblem(problem, needTranslation, function (e, _problem) { + if (e) return cb(e); + + that.saveProblem(_problem); + return cb(null, _problem); + }); + }; + + saveProblem = (problem) => { + const _problem = underscore.omit(problem, ["locked", "state", "starred"]); + return storageUtils.setCache(commUtils.KEYS.problem(problem), _problem); + }; + + updateProblem = (problem, kv) => { + const problems = storageUtils.getCache(commUtils.KEYS.problems); + if (!problems) return false; + + const _problem = problems.find((x) => x.id === problem.id); + if (!_problem) return false; + + underscore.extend(_problem, kv); + return storageUtils.setCache(commUtils.KEYS.problems, problems); + }; + + login = (user, cb) => { + this.logout(user, false); + this.next.login(user, function (e, user) { + if (e) return cb(e); + sessionUtils.saveUser(user); + return cb(null, user); + }); + }; + + logout = (user, purge) => { + if (!user) user = sessionUtils.getUser(); + if (purge) sessionUtils.deleteUser(); + // NOTE: need invalidate any user related cache + sessionUtils.deleteCodingSession(); + return user; + }; +} + +export const pluginObj: CachePlugin = new CachePlugin(); diff --git a/src/childProcessCall/core.ts b/src/rpc/actionChain/chainNode/core.ts similarity index 53% rename from src/childProcessCall/core.ts rename to src/rpc/actionChain/chainNode/core.ts index 2fb9aa9..1767685 100644 --- a/src/childProcessCall/core.ts +++ b/src/rpc/actionChain/chainNode/core.ts @@ -1,76 +1,47 @@ /* - * Filename: https://github.com/ccagml/vscode-leetcode-problem-rating/src/childProcessCall/core.ts - * Path: https://github.com/ccagml/vscode-leetcode-problem-rating - * Created Date: Thursday, October 27th 2022, 7:43:29 pm + * Filename: /home/cc/vscode-leetcode-problem-rating/src/rpc/actionChain/core.ts + * Path: /home/cc/vscode-leetcode-problem-rating + * Created Date: Monday, November 14th 2022, 4:04:31 pm * Author: ccagml * * Copyright (c) 2022 ccagml . All rights reserved. */ +let util = require("util"); -let util = require('util'); +let _ = require("underscore"); +let cheerio = require("cheerio"); -let _ = require('underscore'); -let cheerio = require('cheerio'); +import { storageUtils } from "../../utils/storageUtils"; +import { configUtils } from "../../utils/configUtils"; -// import { log } from "./log"; -import { helper } from "./helper"; -import { storageUtils } from "./storageUtils"; - -import { MyPluginBase } from "./my_plugin_base"; +import { ChainNodeBase } from "../chainNodeBase"; function hasTag(o, tag) { - return Array.isArray(o) && o.some(x => x.indexOf(tag.toLowerCase()) >= 0); + return Array.isArray(o) && o.some((x) => x.indexOf(tag.toLowerCase()) >= 0); } -class CorePlugin extends MyPluginBase { +class CorePlugin extends ChainNodeBase { id = 99999999; - name = 'core'; + name = "core"; builtin = true; - filters = { - query: { - alias: 'query', - type: 'string', - default: '', - describe: [ - 'Filter questions by condition:', - 'Uppercase means negative', - 'e = easy E = m+h', - 'm = medium M = e+h', - 'h = hard H = e+m', - 'd = done D = not done', - 'l = locked L = non locked', - 's = starred S = not starred' - ].join('\n') - }, - tag: { - alias: 'tag', - type: 'array', - default: [], - describe: 'Filter questions by tag' - } - }; - constructor() { super(); } - filterProblems = (opts, cb) => { this.getProblems(!opts.dontTranslate, function (e, problems) { if (e) return cb(e); - for (let q of (opts.query || '').split('')) { + for (let q of (opts.query || "").split("")) { const f = QUERY_HANDLERS[q]; if (!f) continue; - problems = problems.filter(x => f(x, q)); + problems = problems.filter((x) => f(x, q)); } - for (let t of (opts.tag || [])) { + for (let t of opts.tag || []) { problems = problems.filter(function (x) { - return x.category === t || - hasTag(x.companies, t) || - hasTag(x.tags, t); + return x.category === t || hasTag(x.companies, t) || hasTag(x.tags, t); }); } @@ -85,21 +56,20 @@ class CorePlugin extends MyPluginBase { const metaFid = storageUtils.exist(keyword) ? storageUtils.meta(keyword).id : NaN; const problem = problems.find(function (x) { if (keyword?.fid) { - return x.fid + '' === keyword.fid + ''; + return x.fid + "" === keyword.fid + ""; } else if (keyword?.qid) { - return x.id + '' === keyword.qid + ''; + return x.id + "" === keyword.qid + ""; } else { - return x.id + '' === keyword + '' || x.fid + '' === metaFid + '' || x.name === keyword || x.slug === keyword; + return x.id + "" === keyword + "" || x.fid + "" === metaFid + "" || x.name === keyword || x.slug === keyword; } }); - if (!problem) return cb('Problem not found!'); + if (!problem) return cb("Problem not found!"); that.next.getProblem(problem, needTranslation, cb); }); }; starProblem = (problem, starred, cb) => { if (problem.starred === starred) { - return cb(null, starred); } @@ -109,26 +79,29 @@ class CorePlugin extends MyPluginBase { exportProblem = (problem, opts) => { const data = _.extend({}, problem); + // 增加版本信息 + data.LCPTCTX = configUtils.LCPTCTX; + data.allCaseList = storageUtils.getAllCase(problem.desc); // unify format before rendering - data.app = require('./config').app || 'leetcode'; + data.app = configUtils.app || "leetcode"; if (!data.fid) data.fid = data.id; if (!data.lang) data.lang = opts.lang; - data.code = (opts.code || data.code || '').replace(/\r\n/g, '\n'); - data.comment = helper.langToCommentStyle(data.lang); + data.code = (opts.code || data.code || "").replace(/\r\n/g, "\n"); + data.comment = storageUtils.getCommentStyleByLanguage(data.lang); data.percent = data.percent.toFixed(2); - data.testcase = util.inspect(data.testcase || ''); + data.testcase = util.inspect(data.testcase || ""); - if (opts.tpl === 'detailed') { + if (opts.tpl === "detailed") { let desc = data.desc; // Replace with '^' as the power operator - desc = desc.replace(/<\/sup>/gm, '').replace(//gm, '^'); - desc = require('he').decode(cheerio.load(desc).root().text()); + desc = desc.replace(/<\/sup>/gm, "").replace(//gm, "^"); + desc = require("he").decode(cheerio.load(desc).root().text()); // NOTE: wordwrap internally uses '\n' as EOL, so here we have to // remove all '\r' in the raw string. - desc = desc.replace(/\r\n/g, '\n').replace(/^ /mg, ''); - const wrap = require('wordwrap')(79 - data.comment.line.length); - data.desc = wrap(desc).split('\n'); + desc = desc.replace(/\r\n/g, "\n").replace(/^ /gm, ""); + const wrap = require("wordwrap")(79 - data.comment.line.length); + data.desc = wrap(desc).split("\n"); } return storageUtils.render(opts.tpl, data); }; @@ -162,11 +135,10 @@ class CorePlugin extends MyPluginBase { }; } - const isLevel = (x, q) => x.level[0].toLowerCase() === q.toLowerCase(); -const isACed = x => x.state === 'ac'; -const isLocked = x => x.locked; -const isStarred = x => x.starred; +const isACed = (x) => x.state === "ac"; +const isLocked = (x) => x.locked; +const isStarred = (x) => x.starred; const QUERY_HANDLERS = { e: isLevel, @@ -180,7 +152,7 @@ const QUERY_HANDLERS = { d: isACed, D: _.negate(isACed), s: isStarred, - S: _.negate(isStarred) + S: _.negate(isStarred), }; export const corePlugin: CorePlugin = new CorePlugin(); diff --git a/src/childProcessCall/plugins/leetcode.cn.ts b/src/rpc/actionChain/chainNode/leetcode.cn.ts similarity index 53% rename from src/childProcessCall/plugins/leetcode.cn.ts rename to src/rpc/actionChain/chainNode/leetcode.cn.ts index 1137db9..958cd0e 100644 --- a/src/childProcessCall/plugins/leetcode.cn.ts +++ b/src/rpc/actionChain/chainNode/leetcode.cn.ts @@ -1,31 +1,30 @@ /* - * Filename: https://github.com/ccagml/vscode-leetcode-problem-rating/src/childProcessCall/plugins/leetcode.cn.ts - * Path: https://github.com/ccagml/vscode-leetcode-problem-rating - * Created Date: Thursday, October 27th 2022, 7:43:29 pm + * Filename: /home/cc/vscode-leetcode-problem-rating/src/rpc/actionChain/leetcode.cn.ts + * Path: /home/cc/vscode-leetcode-problem-rating + * Created Date: Monday, November 14th 2022, 4:04:31 pm * Author: ccagml * * Copyright (c) 2022 ccagml . All rights reserved. */ +import { ChainNodeBase } from "../chainNodeBase"; -import { MyPluginBase } from "../my_plugin_base"; +let request = require("request"); -let request = require('request'); +import { configUtils } from "../../utils/configUtils"; -import { config } from "../config"; +import { sessionUtils } from "../../utils/sessionUtils"; -import { session } from "../session"; - -class LeetCodeCn extends MyPluginBase { +class LeetCodeCn extends ChainNodeBase { id = 15; - name = 'leetcode.cn'; + name = "leetcode.cn"; builtin = true; constructor() { super(); } init() { - config.fix_cn(); - }; + configUtils.fix_cn(); + } getProblems = (needTranslation, cb) => { let that = this; @@ -39,8 +38,7 @@ class LeetCodeCn extends MyPluginBase { problems.forEach(function (problem) { const title = titles[problem.id]; - if (title) - problem.name = title; + if (title) problem.name = title; }); return cb(null, problems); @@ -52,29 +50,26 @@ class LeetCodeCn extends MyPluginBase { }; getProblemsTitle = (cb) => { - - const opts = makeOpts(config.sys.urls.graphql); - opts.headers.Origin = config.sys.urls.base; - opts.headers.Referer = 'https://leetcode.cn/api/problems/algorithms/'; + const opts = makeOpts(configUtils.sys.urls.graphql); + opts.headers.Origin = configUtils.sys.urls.base; + opts.headers.Referer = "https://leetcode.cn/api/problems/algorithms/"; opts.json = true; opts.body = { query: [ - 'query getQuestionTranslation($lang: String) {', - ' translations: allAppliedQuestionTranslations(lang: $lang) {', - ' title', - ' questionId', - ' __typename', - ' }', - '}' - ].join('\n'), + "query getQuestionTranslation($lang: String) {", + " translations: allAppliedQuestionTranslations(lang: $lang) {", + " title", + " questionId", + " __typename", + " }", + "}", + ].join("\n"), variables: {}, - operationName: 'getQuestionTranslation' + operationName: "getQuestionTranslation", }; - request.post(opts, function (e, resp, body) { - e = checkError(e, resp, 200); if (e) return cb(e); @@ -88,24 +83,23 @@ class LeetCodeCn extends MyPluginBase { }; getQuestionOfToday = (cb) => { - - const opts = makeOpts(config.sys.urls.graphql); - opts.headers.Origin = config.sys.urls.base; - opts.headers.Referer = 'https://leetcode.cn/'; + const opts = makeOpts(configUtils.sys.urls.graphql); + opts.headers.Origin = configUtils.sys.urls.base; + opts.headers.Referer = "https://leetcode.cn/"; opts.json = true; opts.body = { operationName: "questionOfToday", variables: {}, query: [ - 'query questionOfToday {', - ' todayRecord {', - ' date', - ' userStatus', - ' question {', - ' titleSlug', - ' questionId', - ' questionFrontendId', + "query questionOfToday {", + " todayRecord {", + " date", + " userStatus", + " question {", + " titleSlug", + " questionId", + " questionFrontendId", // ' content', // ' stats', // ' likes', @@ -115,17 +109,15 @@ class LeetCodeCn extends MyPluginBase { // ' enableRunCode', // ' metaData', // ' translatedContent', - ' __typename', - ' }', - ' __typename', - ' }', - '}' - ].join('\n'), + " __typename", + " }", + " __typename", + " }", + "}", + ].join("\n"), }; - request.post(opts, function (e, resp, body) { - e = checkError(e, resp, 200); if (e) return cb(e); let result: any = {}; @@ -138,27 +130,26 @@ class LeetCodeCn extends MyPluginBase { }); }; getUserContestP = (username, cb) => { - - const opts = makeOpts(config.sys.urls.noj_go); - opts.headers.Origin = config.sys.urls.base; - opts.headers.Referer = config.sys.urls.u.replace('$username', username); + const opts = makeOpts(configUtils.sys.urls.noj_go); + opts.headers.Origin = configUtils.sys.urls.base; + opts.headers.Referer = configUtils.sys.urls.u.replace("$username", username); opts.json = true; opts.body = { variables: { - userSlug: username + userSlug: username, }, query: [ - ' query userContestRankingInfo($userSlug: String!) {', - ' userContestRanking(userSlug: $userSlug) {', - ' attendedContestsCount', - ' rating', - ' globalRanking', - ' localRanking', - ' globalTotalParticipants', - ' localTotalParticipants', - ' topPercentage', - ' }', + " query userContestRankingInfo($userSlug: String!) {", + " userContestRanking(userSlug: $userSlug) {", + " attendedContestsCount", + " rating", + " globalRanking", + " localRanking", + " globalTotalParticipants", + " localTotalParticipants", + " topPercentage", + " }", // ' userContestRankingHistory(userSlug: $userSlug) {', // ' attended', // ' totalProblems', @@ -173,13 +164,11 @@ class LeetCodeCn extends MyPluginBase { // ' startTime', // ' }', // ' }', - ' }' - ].join('\n'), + " }", + ].join("\n"), }; - request.post(opts, function (e, resp, body) { - e = checkError(e, resp, 200); if (e) return cb(e); @@ -187,55 +176,53 @@ class LeetCodeCn extends MyPluginBase { }); }; - getRatingOnline = (cb) => { const _request = request.defaults({ jar: true }); - _request("https://zerotrac.github.io/leetcode_problem_rating/data.json", function (error, _, body) { + _request("https://zerotrac.github.io/leetcode_problem_rating/data.json", function (error: any, _, body: any) { // console.log(error); // console.log(info); cb(error, body); }); }; - - getTestApi = (value, _) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + getTestApi = (value: any, _) => { const _request = request.defaults({ jar: true }); - _request("https://zerotrac.github.io/leetcode_problem_rating/data.json", function (error, info, body) { - console.log(error); - console.log(info); - let a = body; - console.log(a, value); - }); + _request( + "https://zerotrac.github.io/leetcode_problem_rating/data.json", + function (error: any, info: any, body: any) { + console.log(error); + console.log(info); + let a = body; + console.log(a, value); + } + ); }; } - -function signOpts(opts, user) { - opts.headers.Cookie = 'LEETCODE_SESSION=' + user.sessionId + - ';csrftoken=' + user.sessionCSRF + ';'; - opts.headers['X-CSRFToken'] = user.sessionCSRF; - opts.headers['X-Requested-With'] = 'XMLHttpRequest'; +function signOpts(opts: any, user: any) { + opts.headers.Cookie = "LEETCODE_SESSION=" + user.sessionId + ";csrftoken=" + user.sessionCSRF + ";"; + opts.headers["X-CSRFToken"] = user.sessionCSRF; + opts.headers["X-Requested-With"] = "XMLHttpRequest"; } -function makeOpts(url) { +function makeOpts(url: any) { let opts: any = {}; opts.url = url; opts.headers = {}; - if (session.isLogin()) - signOpts(opts, session.getUser()); + if (sessionUtils.isLogin()) signOpts(opts, sessionUtils.getUser()); return opts; } -function checkError(e, resp, expectedStatus) { +function checkError(e: any, resp: any, expectedStatus: any) { if (!e && resp && resp.statusCode !== expectedStatus) { const code = resp.statusCode; - if (code === 403 || code === 401) { - e = session.errors.EXPIRED; + e = sessionUtils.errors.EXPIRED; } else { - e = { msg: 'http error', statusCode: code }; + e = { msg: "http error", statusCode: code }; } } return e; diff --git a/src/childProcessCall/plugins/leetcode.ts b/src/rpc/actionChain/chainNode/leetcode.ts similarity index 55% rename from src/childProcessCall/plugins/leetcode.ts rename to src/rpc/actionChain/chainNode/leetcode.ts index bfaa5d9..c5e4084 100644 --- a/src/childProcessCall/plugins/leetcode.ts +++ b/src/rpc/actionChain/chainNode/leetcode.ts @@ -1,69 +1,65 @@ /* - * Filename: https://github.com/ccagml/vscode-leetcode-problem-rating/src/childProcessCall/plugins/leetcode.ts - * Path: https://github.com/ccagml/vscode-leetcode-problem-rating - * Created Date: Thursday, October 27th 2022, 7:43:29 pm + * Filename: /home/cc/vscode-leetcode-problem-rating/src/rpc/actionChain/leetcode.ts + * Path: /home/cc/vscode-leetcode-problem-rating + * Created Date: Monday, November 14th 2022, 4:04:31 pm * Author: ccagml * * Copyright (c) 2022 ccagml . All rights reserved. */ +let util = require("util"); +let underscore = require("underscore"); +let request = require("request"); +let prompt_out = require("prompt"); -let util = require('util'); +import { configUtils } from "../../utils/configUtils"; +import { commUtils } from "../../utils/commUtils"; +import { storageUtils } from "../../utils/storageUtils"; +import { reply } from "../../utils/ReplyUtils"; +import { sessionUtils } from "../../utils/sessionUtils"; +import { ChainNodeBase } from "../chainNodeBase"; +import { Queue } from "../../utils/queueUtils"; -let underscore = require('underscore'); -let request = require('request'); -let prompt_out = require('prompt'); - -import { config } from "../config"; -import { helper } from "../helper"; -import { storageUtils } from "../storageUtils"; -import { log } from "../log"; -import { session } from "../session"; -import { MyPluginBase } from "../my_plugin_base"; -import { Queue } from "../queue"; - -class LeetCode extends MyPluginBase { +class LeetCode extends ChainNodeBase { id = 10; - name = 'leetcode'; + name = "leetcode"; builtin = true; constructor() { super(); } signOpts(opts, user) { - opts.headers.Cookie = 'LEETCODE_SESSION=' + user.sessionId + - ';csrftoken=' + user.sessionCSRF + ';'; - opts.headers['X-CSRFToken'] = user.sessionCSRF; - opts.headers['X-Requested-With'] = 'XMLHttpRequest'; - }; + opts.headers.Cookie = "LEETCODE_SESSION=" + user.sessionId + ";csrftoken=" + user.sessionCSRF + ";"; + opts.headers["X-CSRFToken"] = user.sessionCSRF; + opts.headers["X-Requested-With"] = "XMLHttpRequest"; + } makeOpts(url) { const opts: any = {}; opts.url = url; opts.headers = {}; - if (session.isLogin()) - this.signOpts(opts, session.getUser()); + if (sessionUtils.isLogin()) this.signOpts(opts, sessionUtils.getUser()); return opts; - }; + } checkError(e, resp, expectedStatus) { if (!e && resp && resp.statusCode !== expectedStatus) { const code = resp.statusCode; if (code === 403 || code === 401) { - e = session.errors.EXPIRED; + e = sessionUtils.errors.EXPIRED; } else { - e = { msg: 'http error', statusCode: code }; + e = { msg: "http error", statusCode: code }; } } return e; - }; + } init() { - config.app = 'leetcode'; - }; + configUtils.app = "leetcode"; + } getProblems = (_, cb) => { let that = this; @@ -73,24 +69,20 @@ class LeetCode extends MyPluginBase { if (e) { // } else { - problems = problems.concat(_problems); } return cb(e); }); }; - - const q = new Queue(config.sys.categories, {}, getCategory); + const q = new Queue(configUtils.sys.categories, {}, getCategory); q.run(null, function (e) { - return cb(e, problems); }); }; getCategoryProblems = (category, cb) => { - - const opts = this.makeOpts(config.sys.urls.problems.replace('$category', category)); + const opts = this.makeOpts(configUtils.sys.urls.problems.replace("$category", category)); let that = this; request(opts, function (e, resp, body) { @@ -99,27 +91,25 @@ class LeetCode extends MyPluginBase { const json = JSON.parse(body); - if (json.user_name.length === 0) { - - return cb(session.errors.EXPIRED); + return cb(sessionUtils.errors.EXPIRED); } const problems = json.stat_status_pairs .filter((p) => !p.stat.question__hide) .map(function (p) { return { - state: p.status || 'None', + state: p.status || "None", id: p.stat.question_id, fid: p.stat.frontend_question_id, name: p.stat.question__title, slug: p.stat.question__title_slug, - link: config.sys.urls.problem.replace('$slug', p.stat.question__title_slug), + link: configUtils.sys.urls.problem.replace("$slug", p.stat.question__title_slug), locked: p.paid_only, - percent: p.stat.total_acs * 100 / p.stat.total_submitted, - level: helper.levelToName(p.difficulty.level), + percent: (p.stat.total_acs * 100) / p.stat.total_submitted, + level: commUtils.getNameByLevel(p.difficulty.level), starred: p.is_favor, - category: json.category_slug + category: json.category_slug, }; }); @@ -128,51 +118,48 @@ class LeetCode extends MyPluginBase { }; getProblem = (problem, needTranslation, cb) => { + const user = sessionUtils.getUser(); + if (problem.locked && !user.paid) return cb("failed to load locked problem!"); - const user = session.getUser(); - if (problem.locked && !user.paid) return cb('failed to load locked problem!'); - - const opts = this.makeOpts(config.sys.urls.graphql); - opts.headers.Origin = config.sys.urls.base; + const opts = this.makeOpts(configUtils.sys.urls.graphql); + opts.headers.Origin = configUtils.sys.urls.base; opts.headers.Referer = problem.link; opts.json = true; opts.body = { query: [ - 'query getQuestionDetail($titleSlug: String!) {', - ' question(titleSlug: $titleSlug) {', - ' content', - ' stats', - ' likes', - ' dislikes', - ' codeDefinition', - ' sampleTestCase', - ' enableRunCode', - ' metaData', - ' translatedContent', - ' }', - '}' - ].join('\n'), + "query getQuestionDetail($titleSlug: String!) {", + " question(titleSlug: $titleSlug) {", + " content", + " stats", + " likes", + " dislikes", + " codeDefinition", + " sampleTestCase", + " enableRunCode", + " metaData", + " translatedContent", + " }", + "}", + ].join("\n"), variables: { titleSlug: problem.slug }, - operationName: 'getQuestionDetail' + operationName: "getQuestionDetail", }; - let that = this; request.post(opts, function (e, resp, body) { - e = that.checkError(e, resp, 200); if (e) return cb(e); const q = body.data.question; - if (!q) return cb('failed to load problem!'); + if (!q) return cb("failed to load problem!"); problem.totalAC = JSON.parse(q.stats).totalAccepted; problem.totalSubmit = JSON.parse(q.stats).totalSubmission; problem.likes = q.likes; problem.dislikes = q.dislikes; - problem.desc = (q.translatedContent && needTranslation) ? q.translatedContent : q.content; + problem.desc = q.translatedContent && needTranslation ? q.translatedContent : q.content; problem.templates = JSON.parse(q.codeDefinition); problem.testcase = q.sampleTestCase; @@ -185,31 +172,27 @@ class LeetCode extends MyPluginBase { }); }; runCode = (opts, problem, cb) => { - opts.method = 'POST'; - opts.headers.Origin = config.sys.urls.base; + opts.method = "POST"; + opts.headers.Origin = configUtils.sys.urls.base; opts.headers.Referer = problem.link; opts.json = true; - opts._delay = opts._delay || config.network.delay || 1; // in seconds + opts._delay = opts._delay || configUtils.network.delay || 1; // in seconds opts.body = opts.body || {}; underscore.extendOwn(opts.body, { lang: problem.lang, question_id: parseInt(problem.id, 10), test_mode: false, - typed_code: storageUtils.codeData(problem.file) + typed_code: storageUtils.codeData(problem.file), }); - let that = this; request(opts, function (e, resp, body) { - e = that.checkError(e, resp, 200); if (e) return cb(e); if (body.error) { - if (!body.error.includes('too soon')) - return cb(body.error); - + if (!body.error.includes("too soon")) return cb(body.error); ++opts._delay; @@ -224,21 +207,18 @@ class LeetCode extends MyPluginBase { }); }; - verifyResult = (task, queue, cb) => { const opts = queue.ctx.opts; - opts.method = 'GET'; - opts.url = config.sys.urls.verify.replace('$id', task.id); - + opts.method = "GET"; + opts.url = configUtils.sys.urls.verify.replace("$id", task.id); let that = this; request(opts, function (e, resp, body) { - e = that.checkError(e, resp, 200); if (e) return cb(e); let result = JSON.parse(body); - if (result.state === 'SUCCESS') { + if (result.state === "SUCCESS") { result = that.formatResult(result); underscore.extendOwn(result, task); queue.ctx.results.push(result); @@ -253,17 +233,18 @@ class LeetCode extends MyPluginBase { const x: any = { ok: result.run_success, lang: result.lang, - runtime: result.status_runtime || '', - runtime_percentile: result.runtime_percentile || '', - memory: result.status_memory || '', - memory_percentile: result.memory_percentile || '', + runtime: result.status_runtime || "", + runtime_percentile: result.runtime_percentile || "", + memory: result.status_memory || "", + memory_percentile: result.memory_percentile || "", state: result.status_msg, - testcase: util.inspect(result.input || result.last_testcase || ''), + testcase: util.inspect(result.input || result.last_testcase || ""), passed: result.total_correct || 0, - total: result.total_testcases || 0 + total: result.total_testcases || 0, }; - x.error = underscore.chain(result) + x.error = underscore + .chain(result) .pick((v, k) => /_error$/.test(k) && v.length > 0) .values() .value(); @@ -272,7 +253,7 @@ class LeetCode extends MyPluginBase { // It's testing let output = result.code_output || []; if (Array.isArray(output)) { - output = output.join('\n'); + output = output.join("\n"); } x.stdout = util.inspect(output); x.answer = result.code_answer; @@ -287,27 +268,24 @@ class LeetCode extends MyPluginBase { // make sure we pass eveything! if (x.passed !== x.total) x.ok = false; - if (x.state !== 'Accepted') x.ok = false; + if (x.state !== "Accepted") x.ok = false; if (x.error.length > 0) x.ok = false; return x; }; testProblem = (problem, cb) => { - - const opts = this.makeOpts(config.sys.urls.test.replace('$slug', problem.slug)); + const opts = this.makeOpts(configUtils.sys.urls.test.replace("$slug", problem.slug)); opts.body = { data_input: problem.testcase }; let that = this; this.runCode(opts, problem, function (e, task) { if (e) return cb(e); - const tasks = [ - { type: 'Actual', id: task.interpret_id }, - ]; + const tasks = [{ type: "Actual", id: task.interpret_id }]; // Used by LeetCode-CN if (task.interpret_expected_id) { - tasks.push({ type: 'Expected', id: task.interpret_expected_id }); + tasks.push({ type: "Expected", id: task.interpret_expected_id }); } const q = new Queue(tasks, { opts: opts, results: [] }, that.verifyResult); q.run(null, function (e, ctx) { @@ -317,14 +295,13 @@ class LeetCode extends MyPluginBase { }; submitProblem = (problem, cb) => { - - const opts = this.makeOpts(config.sys.urls.submit.replace('$slug', problem.slug)); - opts.body = { judge_type: 'large' }; + const opts = this.makeOpts(configUtils.sys.urls.submit.replace("$slug", problem.slug)); + opts.body = { judge_type: "large" }; let that = this; this.runCode(opts, problem, function (e, task) { if (e) return cb(e); - const tasks = [{ type: 'Actual', id: task.submission_id }]; + const tasks = [{ type: "Actual", id: task.submission_id }]; const q = new Queue(tasks, { opts: opts, results: [] }, that.verifyResult); q.run(null, function (e, ctx) { return cb(e, ctx.results); @@ -333,9 +310,8 @@ class LeetCode extends MyPluginBase { }; getSubmissions = (problem, cb) => { - - const opts = this.makeOpts(config.sys.urls.submissions.replace('$slug', problem.slug)); - opts.headers.Referer = config.sys.urls.problem.replace('$slug', problem.slug); + const opts = this.makeOpts(configUtils.sys.urls.submissions.replace("$slug", problem.slug)); + opts.headers.Referer = configUtils.sys.urls.problem.replace("$slug", problem.slug); let that = this; request(opts, function (e, resp, body) { e = that.checkError(e, resp, 200); @@ -344,15 +320,14 @@ class LeetCode extends MyPluginBase { // FIXME: this only return the 1st 20 submissions, we should get next if necessary. const submissions = JSON.parse(body).submissions_dump; for (const submission of submissions) - submission.id = underscore.last(underscore.compact(submission.url.split('/'))); + submission.id = underscore.last(underscore.compact(submission.url.split("/"))); return cb(null, submissions); }); }; getSubmission = (submission, cb) => { - - const opts = this.makeOpts(config.sys.urls.submission.replace('$id', submission.id)); + const opts = this.makeOpts(configUtils.sys.urls.submission.replace("$id", submission.id)); let that = this; request(opts, function (e, resp, body) { e = that.checkError(e, resp, 200); @@ -368,38 +343,33 @@ class LeetCode extends MyPluginBase { }; starProblem = (problem, starred, cb) => { - - const user = session.getUser(); - const operationName = starred ? 'addQuestionToFavorite' : 'removeQuestionFromFavorite'; - const opts = this.makeOpts(config.sys.urls.graphql); - opts.headers.Origin = config.sys.urls.base; + const user = sessionUtils.getUser(); + const operationName = starred ? "addQuestionToFavorite" : "removeQuestionFromFavorite"; + const opts = this.makeOpts(configUtils.sys.urls.graphql); + opts.headers.Origin = configUtils.sys.urls.base; opts.headers.Referer = problem.link; opts.json = true; opts.body = { query: `mutation ${operationName}($favoriteIdHash: String!, $questionId: String!) {\n ${operationName}(favoriteIdHash: $favoriteIdHash, questionId: $questionId) {\n ok\n error\n favoriteIdHash\n questionId\n __typename\n }\n}\n`, - variables: { favoriteIdHash: user.hash, questionId: '' + problem.id }, - operationName: operationName + variables: { favoriteIdHash: user.hash, questionId: "" + problem.id }, + operationName: operationName, }; - let that = this; - request.post(opts, function (e, resp, _) { - + // eslint-disable-next-line @typescript-eslint/no-unused-vars + request.post(opts, function (e: any, resp: any, _) { e = that.checkError(e, resp, 200); if (e) return cb(e); return cb(null, starred); }); }; - getFavorites = (cb) => { - - const opts = this.makeOpts(config.sys.urls.favorites); - + getFavorites = (cb: any) => { + const opts = this.makeOpts(configUtils.sys.urls.favorites); let that = this; request(opts, function (e, resp, body) { - e = that.checkError(e, resp, 200); if (e) return cb(e); @@ -408,27 +378,18 @@ class LeetCode extends MyPluginBase { }); }; - getUserInfo = (cb) => { + getUserInfo = (cb: any) => { let that = this; - const opts = this.makeOpts(config.sys.urls.graphql); - opts.headers.Origin = config.sys.urls.base; - opts.headers.Referer = config.sys.urls.base; + const opts = this.makeOpts(configUtils.sys.urls.graphql); + opts.headers.Origin = configUtils.sys.urls.base; + opts.headers.Referer = configUtils.sys.urls.base; opts.json = true; opts.body = { - query: [ - '{', - ' user {', - ' username', - ' isCurrentUserPremium', - ' }', - '}' - ].join('\n'), - variables: {} + query: ["{", " user {", " username", " isCurrentUserPremium", " }", "}"].join("\n"), + variables: {}, }; - request.post(opts, function (e, resp, body) { - e = that.checkError(e, resp, 200); if (e) return cb(e); @@ -437,77 +398,68 @@ class LeetCode extends MyPluginBase { }); }; - - runSession = (method, data, cb) => { - const opts = this.makeOpts(config.sys.urls.session); + runSession = (method: any, data: any, cb: any) => { + const opts = this.makeOpts(configUtils.sys.urls.session); opts.json = true; opts.method = method; opts.body = data; - let that = this; request(opts, function (e, resp, body) { - e = that.checkError(e, resp, 200); - if (e && e.statusCode === 302) e = session.errors.EXPIRED; + if (e && e.statusCode === 302) e = sessionUtils.errors.EXPIRED; return e ? cb(e) : cb(null, body.sessions); }); }; getSessions = (cb) => { - - this.runSession('POST', {}, cb); + this.runSession("POST", {}, cb); }; activateSession = (session, cb) => { - const data = { func: 'activate', target: session.id }; - this.runSession('PUT', data, cb); + const data = { func: "activate", target: session.id }; + this.runSession("PUT", data, cb); }; createSession = (name, cb) => { - - const data = { func: 'create', name: name }; - this.runSession('PUT', data, cb); + const data = { func: "create", name: name }; + this.runSession("PUT", data, cb); }; deleteSession = (session, cb) => { - const data = { target: session.id }; - this.runSession('DELETE', data, cb); + this.runSession("DELETE", data, cb); }; - signin = (user, cb) => { - const isCN = config.app === 'leetcode.cn'; - const spin = isCN ? helper.spin('Signing in leetcode.cn') : helper.spin('Signing in leetcode.com'); + signin = (user: any, cb: any) => { let that = this; - request(config.sys.urls.login, function (e, resp, _) { - spin.stop(); + // eslint-disable-next-line @typescript-eslint/no-unused-vars + request(configUtils.sys.urls.login, function (e: any, resp: any, _) { e = that.checkError(e, resp, 200); if (e) return cb(e); - - user.loginCSRF = helper.getSetCookieValue(resp, 'csrftoken'); - + user.loginCSRF = commUtils.getSetCookieValue(resp, "csrftoken"); const opts = { - url: config.sys.urls.login, + url: configUtils.sys.urls.login, headers: { - Origin: config.sys.urls.base, - Referer: config.sys.urls.login, - Cookie: 'csrftoken=' + user.loginCSRF + ';' + Origin: configUtils.sys.urls.base, + Referer: configUtils.sys.urls.login, + Cookie: "csrftoken=" + user.loginCSRF + ";", }, form: { csrfmiddlewaretoken: user.loginCSRF, login: user.login, - password: user.pass - } + password: user.pass, + }, }; - request.post(opts, function (e, resp, _) { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + request.post(opts, function (e: any, resp: any, _) { if (e) return cb(e); - if (resp.statusCode !== 302) return cb('invalid password?'); + if (resp.statusCode !== 302) return cb("invalid password?"); - user.sessionCSRF = helper.getSetCookieValue(resp, 'csrftoken'); - user.sessionId = helper.getSetCookieValue(resp, 'LEETCODE_SESSION'); - session.saveUser(user); + user.sessionCSRF = commUtils.getSetCookieValue(resp, "csrftoken"); + user.sessionId = commUtils.getSetCookieValue(resp, "LEETCODE_SESSION"); + sessionUtils.saveUser(user); return cb(null, user); }); }); @@ -517,15 +469,15 @@ class LeetCode extends MyPluginBase { let that = this; this.getFavorites(function (e, favorites) { if (!e) { - const f = favorites.favorites.private_favorites.find((f) => f.name === 'Favorite'); + const f = favorites.favorites.private_favorites.find((f) => f.name === "Favorite"); if (f) { user.hash = f.id_hash; user.name = favorites.user_name; } else { - log.warn('Favorite not found?'); + reply.warn("Favorite not found?"); } } else { - log.warn('Failed to retrieve user favorites: ' + e); + reply.warn("Failed to retrieve user favorites: " + e); } that.getUserInfo(function (e, _user) { @@ -533,7 +485,7 @@ class LeetCode extends MyPluginBase { user.paid = _user.isCurrentUserPremium; user.name = _user.username; } - session.saveUser(user); + sessionUtils.saveUser(user); return cb(null, user); }); }); @@ -553,7 +505,7 @@ class LeetCode extends MyPluginBase { const reCsrfResult = csrfPattern.exec(cookie); const reSessionResult = SessionPattern.exec(cookie); if (reSessionResult === null || reCsrfResult === null) { - return cb('invalid cookie?'); + return cb("invalid cookie?"); } return { sessionId: reSessionResult[1], @@ -563,15 +515,16 @@ class LeetCode extends MyPluginBase { requestLeetcodeAndSave = (request, leetcodeUrl, user, cb) => { let that = this; + // eslint-disable-next-line @typescript-eslint/no-unused-vars request.get({ url: leetcodeUrl }, function (_, resp, __) { const redirectUri = resp.request.uri.href; - if (redirectUri !== config.sys.urls.leetcode_redirect) { - return cb('Login failed. Please make sure the credential is correct.'); + if (redirectUri !== configUtils.sys.urls.leetcode_redirect) { + return cb("Login failed. Please make sure the credential is correct."); } const cookieData = that.parseCookie(resp.request.headers.cookie, cb); user.sessionId = cookieData.sessionId; user.sessionCSRF = cookieData.sessionCSRF; - session.saveUser(user); + sessionUtils.saveUser(user); that.getUser(user, cb); }); }; @@ -580,158 +533,156 @@ class LeetCode extends MyPluginBase { const cookieData = this.parseCookie(user.cookie, cb); user.sessionId = cookieData.sessionId; user.sessionCSRF = cookieData.sessionCSRF; - session.saveUser(user); + sessionUtils.saveUser(user); this.getUser(user, cb); }; githubLogin = (user, cb) => { - const urls = config.sys.urls; + const urls = configUtils.sys.urls; const leetcodeUrl = urls.github_login; const _request = request.defaults({ jar: true }); let that = this; _request(urls.github_login_request, function (_, __, body) { - const authenticityToken = body.match(/name="authenticity_token" value="(.*?)"/); let gaId = body.match(/name="ga_id" value="(.*?)"/); if (!gaId) { - gaId = ''; + gaId = ""; } let requiredField = body.match(/name="required_field_(.*?)"/); const timestamp = body.match(/name="timestamp" value="(.*?)"/); const timestampSecret = body.match(/name="timestamp_secret" value="(.*?)"/); if (!(authenticityToken && timestamp && timestampSecret && requiredField)) { - return cb('Get GitHub payload failed'); + return cb("Get GitHub payload failed"); } - requiredField = 'required_field_' + requiredField[1]; + requiredField = "required_field_" + requiredField[1]; const options = { url: urls.github_session_request, - method: 'POST', + method: "POST", headers: { - 'Content-Type': 'application/x-www-form-urlencoded', + "Content-Type": "application/x-www-form-urlencoded", }, followAllRedirects: true, form: { - 'login': user.login, - 'password': user.pass, - 'authenticity_token': authenticityToken[1], - 'commit': encodeURIComponent('Sign in'), - 'ga_id': gaId, - 'webauthn-support': 'supported', - 'webauthn-iuvpaa-support': 'unsupported', - 'return_to': '', - 'requiredField': '', - 'timestamp': timestamp[1], - 'timestamp_secret': timestampSecret[1], + login: user.login, + password: user.pass, + authenticity_token: authenticityToken[1], + commit: encodeURIComponent("Sign in"), + ga_id: gaId, + "webauthn-support": "supported", + "webauthn-iuvpaa-support": "unsupported", + return_to: "", + requiredField: "", + timestamp: timestamp[1], + timestamp_secret: timestampSecret[1], }, }; _request(options, function (_, resp, body) { - if (resp.statusCode !== 200) { - return cb('GitHub login failed'); + return cb("GitHub login failed"); } if (resp.request.uri.href !== urls.github_tf_redirect) { return that.requestLeetcodeAndSave(_request, leetcodeUrl, user, cb); } prompt_out.colors = false; - prompt_out.message = ''; + prompt_out.message = ""; prompt_out.start(); - prompt_out.get([ - { - name: 'twoFactorCode', - required: true - } - ], function (e, result) { - if (e) return log.info(e); - const authenticityTokenTwoFactor = body.match(/name="authenticity_token" value="(.*?)"/); - if (authenticityTokenTwoFactor === null) { - return cb('Get GitHub two-factor token failed'); - } - const optionsTwoFactor = { - url: urls.github_tf_session_request, - method: 'POST', - headers: { - 'Content-Type': 'application/x-www-form-urlencoded', - }, - followAllRedirects: true, - form: { - 'otp': result.twoFactorCode, - 'authenticity_token': authenticityTokenTwoFactor[1], - 'utf8': encodeURIComponent('✓'), + prompt_out.get( + [ + { + name: "twoFactorCode", + required: true, }, - }; - _request(optionsTwoFactor, function (_, resp, __) { - - if (resp.request.uri.href === urls.github_tf_session_request) { - return cb('Invalid two-factor code please check'); + ], + function (e, result) { + if (e) return reply.info(e); + const authenticityTokenTwoFactor = body.match(/name="authenticity_token" value="(.*?)"/); + if (authenticityTokenTwoFactor === null) { + return cb("Get GitHub two-factor token failed"); } - that.requestLeetcodeAndSave(_request, leetcodeUrl, user, cb); - }); - }); + const optionsTwoFactor = { + url: urls.github_tf_session_request, + method: "POST", + headers: { + "Content-Type": "application/x-www-form-urlencoded", + }, + followAllRedirects: true, + form: { + otp: result.twoFactorCode, + authenticity_token: authenticityTokenTwoFactor[1], + utf8: encodeURIComponent("✓"), + }, + }; + // eslint-disable-next-line @typescript-eslint/no-unused-vars + _request(optionsTwoFactor, function (_, resp, __) { + if (resp.request.uri.href === urls.github_tf_session_request) { + return cb("Invalid two-factor code please check"); + } + that.requestLeetcodeAndSave(_request, leetcodeUrl, user, cb); + }); + } + ); }); }); }; linkedinLogin = (user, cb) => { - const urls = config.sys.urls; + const urls = configUtils.sys.urls; const leetcodeUrl = urls.linkedin_login; const _request = request.defaults({ jar: true, headers: { - 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36' - } + "User-Agent": + "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36", + }, }); let that = this; _request(urls.linkedin_login_request, function (_, resp, body) { - if (resp.statusCode !== 200) { - return cb('Get LinkedIn session failed'); + return cb("Get LinkedIn session failed"); } const csrfToken = body.match(/input type="hidden" name="csrfToken" value="(.*?)"/); const loginCsrfToken = body.match(/input type="hidden" name="loginCsrfParam" value="(.*?)"/); const sIdString = body.match(/input type="hidden" name="sIdString" value="(.*?)"/); const pageInstance = body.match(/input type="hidden" name="pageInstance" value="(.*?)"/); if (!(csrfToken && loginCsrfToken && sIdString && pageInstance)) { - return cb('Get LinkedIn payload failed'); + return cb("Get LinkedIn payload failed"); } const options = { url: urls.linkedin_session_request, - method: 'POST', + method: "POST", headers: { - 'Content-Type': 'application/x-www-form-urlencoded', + "Content-Type": "application/x-www-form-urlencoded", }, followAllRedirects: true, form: { - 'csrfToken': csrfToken[1], - 'session_key': user.login, - 'ac': 2, - 'sIdString': sIdString[1], - 'parentPageKey': 'd_checkpoint_lg_consumerLogin', - 'pageInstance': pageInstance[1], - 'trk': 'public_profile_nav-header-signin', - 'authUUID': '', - 'session_redirect': 'https://www.linkedin.com/feed/', - 'loginCsrfParam': loginCsrfToken[1], - 'fp_data': 'default', - '_d': 'd', - 'showGoogleOneTapLogin': true, - 'controlId': 'd_checkpoint_lg_consumerLogin-login_submit_button', - 'session_password': user.pass, - 'loginFlow': 'REMEMBER_ME_OPTIN' + csrfToken: csrfToken[1], + session_key: user.login, + ac: 2, + sIdString: sIdString[1], + parentPageKey: "d_checkpoint_lg_consumerLogin", + pageInstance: pageInstance[1], + trk: "public_profile_nav-header-signin", + authUUID: "", + session_redirect: "https://www.linkedin.com/feed/", + loginCsrfParam: loginCsrfToken[1], + fp_data: "default", + _d: "d", + showGoogleOneTapLogin: true, + controlId: "d_checkpoint_lg_consumerLogin-login_submit_button", + session_password: user.pass, + loginFlow: "REMEMBER_ME_OPTIN", }, }; + // eslint-disable-next-line @typescript-eslint/no-unused-vars _request(options, function (_, resp, __) { - if (resp.statusCode !== 200) { - return cb('LinkedIn login failed'); + return cb("LinkedIn login failed"); } that.requestLeetcodeAndSave(_request, leetcodeUrl, user, cb); }); }); }; - } - - export const pluginObj: LeetCode = new LeetCode(); diff --git a/src/childProcessCall/plugins/retry.ts b/src/rpc/actionChain/chainNode/retry.ts similarity index 62% rename from src/childProcessCall/plugins/retry.ts rename to src/rpc/actionChain/chainNode/retry.ts index 8ca06fa..26ae28c 100644 --- a/src/childProcessCall/plugins/retry.ts +++ b/src/rpc/actionChain/chainNode/retry.ts @@ -1,44 +1,43 @@ /* - * Filename: https://github.com/ccagml/vscode-leetcode-problem-rating/src/childProcessCall/plugins/retry.ts - * Path: https://github.com/ccagml/vscode-leetcode-problem-rating - * Created Date: Thursday, October 27th 2022, 7:43:29 pm + * Filename: /home/cc/vscode-leetcode-problem-rating/src/rpc/actionChain/retry.ts + * Path: /home/cc/vscode-leetcode-problem-rating + * Created Date: Monday, November 14th 2022, 4:04:31 pm * Author: ccagml * * Copyright (c) 2022 ccagml . All rights reserved. */ +import { ChainNodeBase } from "../chainNodeBase"; +import { configUtils } from "../../utils/configUtils"; +import { sessionUtils } from "../../utils/sessionUtils"; - -import { MyPluginBase } from "../my_plugin_base"; -import { config } from "../config"; -import { session } from "../session"; - - -class RetryPlugin extends MyPluginBase { +class RetryPlugin extends ChainNodeBase { id = 30; - name = 'retry'; + name = "retry"; builtin = true; count = {}; canRetry = (e, name) => { - return config.autologin.enable && - (e === session.errors.EXPIRED) && - (this.count[name] || 0) < config.autologin.retry; + return ( + configUtils.autologin.enable && + e === sessionUtils.errors.EXPIRED && + (this.count[name] || 0) < configUtils.autologin.retry + ); }; init = () => { const names = [ - 'activateSession', - 'createSession', - 'deleteSession', - 'getProblems', - 'getProblem', - 'getSessions', - 'getSubmissions', - 'getSubmission', - 'getFavorites', - 'testProblem', - 'submitProblem', - 'starProblem' + "activateSession", + "createSession", + "deleteSession", + "getProblems", + "getProblem", + "getSessions", + "getSubmissions", + "getSubmission", + "getFavorites", + "testProblem", + "submitProblem", + "starProblem", ]; let that = this; for (let name of names) { @@ -73,10 +72,8 @@ class RetryPlugin extends MyPluginBase { // expired immediately. In that case we will try to re-login in // the backend to give a seamless user experience. relogin = (cb) => { - - const user = session.getUser(); + const user = sessionUtils.getUser(); if (!user) { - return cb(); } @@ -89,8 +86,6 @@ class RetryPlugin extends MyPluginBase { return cb(); }); }; - } - export const pluginObj: RetryPlugin = new RetryPlugin(); diff --git a/src/rpc/actionChain/chainNode/solution.discuss.ts b/src/rpc/actionChain/chainNode/solution.discuss.ts new file mode 100644 index 0000000..35afd37 --- /dev/null +++ b/src/rpc/actionChain/chainNode/solution.discuss.ts @@ -0,0 +1,110 @@ +/* + * Filename: /home/cc/vscode-leetcode-problem-rating/src/rpc/actionChain/solution.discuss.ts + * Path: /home/cc/vscode-leetcode-problem-rating + * Created Date: Monday, November 14th 2022, 4:04:31 pm + * Author: ccagml + * + * Copyright (c) 2022 ccagml . All rights reserved. + */ + +let request = require("request"); + +import { reply } from "../../utils/ReplyUtils"; +import { sessionUtils } from "../../utils/sessionUtils"; +import { ChainNodeBase } from "../chainNodeBase"; + +class SolutionDiscuss extends ChainNodeBase { + id = 200; + name = "solution.discuss"; + builtin = true; + constructor() { + super(); + } + + getProblem = (problem, needTranslation, cb) => { + this.next.getProblem(problem, needTranslation, function (e, problem) { + if (e || !sessionUtils.argv.solution) return cb(e, problem); + + let lang = sessionUtils.argv.lang; + getSolution(problem, lang, function (e, solution) { + if (e) return cb(e); + if (!solution) return reply.error("Solution not found for " + lang); + + let link = URL_DISCUSS.replace("$slug", problem.slug).replace("$id", solution.id); + let content = solution.post.content.replace(/\\n/g, "\n").replace(/\\t/g, "\t"); + + reply.info(); + reply.info(problem.name); + reply.info(); + reply.info(solution.title); + reply.info(); + reply.info(link); + reply.info(); + reply.info("* Lang: " + lang); + reply.info("* Author: " + solution.post.author.username); + reply.info("* Votes: " + solution.post.voteCount); + reply.info(); + reply.info(content); + }); + }); + }; +} + +let URL_DISCUSSES = "https://leetcode.com/graphql"; +let URL_DISCUSS = "https://leetcode.com/problems/$slug/discuss/$id"; + +function getSolution(problem, lang, cb) { + if (!problem) return cb(); + + if (lang === "python3") lang = "python"; + + let opts = { + url: URL_DISCUSSES, + json: true, + body: { + query: [ + "query questionTopicsList($questionId: String!, $orderBy: TopicSortingOption, $skip: Int, $query: String, $first: Int!, $tags: [String!]) {", + " questionTopicsList(questionId: $questionId, orderBy: $orderBy, skip: $skip, query: $query, first: $first, tags: $tags) {", + " ...TopicsList", + " }", + "}", + "fragment TopicsList on TopicConnection {", + " totalNum", + " edges {", + " node {", + " id", + " title", + " post {", + " content", + " voteCount", + " author {", + " username", + " }", + " }", + " }", + " }", + "}", + ].join("\n"), + + operationName: "questionTopicsList", + variables: JSON.stringify({ + query: "", + first: 1, + skip: 0, + orderBy: "most_votes", + questionId: "" + problem.id, + tags: [lang], + }), + }, + }; + request(opts, function (e, resp, body) { + if (e) return cb(e); + if (resp.statusCode !== 200) return cb({ msg: "http error", statusCode: resp.statusCode }); + + const solutions = body.data.questionTopicsList.edges; + const solution = solutions.length > 0 ? solutions[0].node : null; + return cb(null, solution); + }); +} + +export const pluginObj: SolutionDiscuss = new SolutionDiscuss(); diff --git a/src/rpc/actionChain/chainNodeBase.ts b/src/rpc/actionChain/chainNodeBase.ts new file mode 100644 index 0000000..3147fdb --- /dev/null +++ b/src/rpc/actionChain/chainNodeBase.ts @@ -0,0 +1,117 @@ +import { commUtils } from "../utils/commUtils"; +import { storageUtils } from "../utils/storageUtils"; + +export class ChainNodeBase { + next: ChainNodeBase; // 下一个点 + enabled: boolean; + builtin: boolean = true; + name: string; // 点的名称 + deleted: boolean; + + public init() {} + + public save(): void { + const stats = storageUtils.getCache(commUtils.KEYS.plugins) || {}; + + if (this.deleted) delete stats[this.name]; + else stats[this.name] = this.enabled; + + storageUtils.setCache(commUtils.KEYS.plugins, stats); + } + + public setNext(next: ChainNodeBase): void { + Object.setPrototypeOf(this, next); + this.next = next; + } + public getProblems(Translate: boolean, cb: Function): void { + this.next.getProblems(Translate, cb); + } + public getQuestionOfToday(cb: Function): void { + this.next.getQuestionOfToday(cb); + } + + public getRatingOnline(cb: Function): void { + this.next.getRatingOnline(cb); + } + + public getTestApi(username, cb: Function): void { + this.next.getTestApi(username, cb); + } + public getUserContestP(username, cb: Function): void { + this.next.getUserContestP(username, cb); + } + public getProblemsTitle(cb: Function): void { + this.next.getProblemsTitle(cb); + } + public createSession(a, cb: Function): void { + this.next.createSession(a, cb); + } + public getSessions(cb: Function): void { + this.next.getSessions(cb); + } + public activateSession(s, cb: Function): void { + this.next.activateSession(s, cb); + } + public deleteSession(s, cb: Function): void { + this.next.deleteSession(s, cb); + } + public updateProblem(a, b): void { + this.next.updateProblem(a, b); + } + public getSubmissions(s, cb: Function): void { + this.next.getSubmissions(s, cb); + } + public getSubmission(s, cb: Function): void { + this.next.getSubmission(s, cb); + } + public submitProblem(s, cb: Function): void { + this.next.submitProblem(s, cb); + } + public testProblem(s, cb: Function): void { + this.next.testProblem(s, cb); + } + public login(user, cb: Function): void { + this.next.login(user, cb); + } + public logout(user, cb): void { + this.next.logout(user, cb); + } + public githubLogin(user, cb: Function): void { + this.next.githubLogin(user, cb); + } + public linkedinLogin(user, cb: Function): void { + this.next.linkedinLogin(user, cb); + } + public cookieLogin(user, cb: Function): void { + this.next.cookieLogin(user, cb); + } + public filterProblems(opts, cb: Function): void { + this.next.filterProblems(opts, cb); + } + + public getProblem(keyword, needTranslation, cb: Function): void { + this.next.getProblem(keyword, needTranslation, cb); + } + + public starProblem(problem, starred, cb: Function): void { + this.next.starProblem(problem, starred, cb); + } + public exportProblem(problem, opts): void { + this.next.exportProblem(problem, opts); + } + + public getTodayQuestion(cb: Function): void { + this.next.getTodayQuestion(cb); + } + + public getQueryZ(username, cb: Function): void { + this.next.getQueryZ(username, cb); + } + + public getUserContest(username, cb: Function): void { + this.next.getUserContest(username, cb); + } + public getRating(cb: Function): void { + this.next.getRating(cb); + } +} diff --git a/src/rpc/childMain.ts b/src/rpc/childMain.ts new file mode 100644 index 0000000..f7e2fb9 --- /dev/null +++ b/src/rpc/childMain.ts @@ -0,0 +1,37 @@ +/* + * Filename: https://github.com/ccagml/vscode-leetcode-problem-rating/src/rpc/cli.ts + * Path: https://github.com/ccagml/vscode-leetcode-problem-rating + * Created Date: Thursday, October 27th 2022, 7:43:29 pm + * Author: ccagml + * + * Copyright (c) 2022 ccagml . All rights reserved. + */ + +import { chainMgr } from "./actionChain/chainManager"; +import { corePlugin } from "./actionChain/chainNode/core"; +import { configUtils } from "./utils/configUtils"; +import { reply } from "./utils/ReplyUtils"; +import { storageUtils } from "./utils/storageUtils"; +import { apiFactory } from "./factory/apiFactory"; +import { IApi } from "./factory/apiBase"; + +class Main { + constructor() { + this.exec(); + } + public exec() { + process.stdout.on("error", function (e) { + if (e.code === "EPIPE") process.exit(); + }); + configUtils.init(JSON.parse(process.env.ccagml || "{}")); + reply.init(); + storageUtils.init(); + chainMgr.init(corePlugin); + + let com_str: string = process.argv[2]; + let curApi: IApi | undefined = apiFactory.getApi(com_str); + curApi?.call(curApi?.callArg(process.argv)); + } +} + +export const main: Main = new Main(); diff --git a/src/rpc/factory/api/cacheApi.ts b/src/rpc/factory/api/cacheApi.ts new file mode 100644 index 0000000..e164128 --- /dev/null +++ b/src/rpc/factory/api/cacheApi.ts @@ -0,0 +1,49 @@ +/* + * Filename: /home/cc/vscode-leetcode-problem-rating/src/rpc/factory/api/cacheApi.ts + * Path: /home/cc/vscode-leetcode-problem-rating + * Created Date: Thursday, November 17th 2022, 11:44:14 am + * Author: ccagml + * + * Copyright (c) 2022 ccagml . All rights reserved. + */ + +import { storageUtils } from "../../utils/storageUtils"; +import { sessionUtils } from "../../utils/sessionUtils"; +import { ApiBase } from "../apiBase"; + +class CacheApi extends ApiBase { + constructor() { + super(); + } + + callArg(argv) { + let argv_config = this.api_argv().option("d", { + alias: "delete", + type: "boolean", + describe: "Delete cache by keyword", + default: false, + }); + argv_config.parseArgFromCmd(argv); + + return argv_config.get_result(); + } + + call(argv) { + sessionUtils.argv = argv; + + const name = argv.keyword || ""; + const isInteger = Number.isInteger(Number(name)); + + const all_data_file = storageUtils.listCache().filter(function (f) { + return name.length === 0 || (isInteger ? f.name.startsWith(name + ".") : f.name === name); + }); + + if (argv.delete) { + for (let f of all_data_file) { + storageUtils.delCache(f.name); + } + } + } +} + +export const cacheApi: CacheApi = new CacheApi(); diff --git a/src/rpc/factory/api/listApi.ts b/src/rpc/factory/api/listApi.ts new file mode 100644 index 0000000..5c5e6cb --- /dev/null +++ b/src/rpc/factory/api/listApi.ts @@ -0,0 +1,91 @@ +/* + * Filename: /home/cc/vscode-leetcode-problem-rating/src/rpc/factory/api/listApi.ts + * Path: /home/cc/vscode-leetcode-problem-rating + * Created Date: Thursday, November 17th 2022, 11:44:14 am + * Author: ccagml + * + * Copyright (c) 2022 ccagml . All rights reserved. + */ + +import { reply } from "../../utils/ReplyUtils"; +import { sessionUtils } from "../../utils/sessionUtils"; +import { ApiBase } from "../apiBase"; +import { chainMgr } from "../../actionChain/chainManager"; + +class ListApi extends ApiBase { + constructor() { + super(); + } + + callArg(argv) { + let argv_config = this.api_argv() + .option("q", { + alias: "query", + type: "string", + default: "", + describe: [ + "Filter questions by condition:", + "Uppercase means negative", + "e = easy E = m+h", + "m = medium M = e+h", + "h = hard H = e+m", + "d = done D = not done", + "l = locked L = non locked", + "s = starred S = not starred", + ].join("\n"), + }) + .option("s", { + alias: "stat", + type: "boolean", + default: false, + describe: "Show statistics of listed questions", + }) + .option("t", { + alias: "tag", + type: "array", + default: [], + describe: "Filter questions by tag", + }) + .option("x", { + alias: "extra", + type: "boolean", + default: false, + describe: "Show extra details: category, companies, tags.", + }) + .option("T", { + alias: "dontTranslate", + type: "boolean", + default: false, + describe: "Set to true to disable endpoint's translation", + }) + .positional("keyword", { + type: "string", + default: "", + describe: "Filter questions by keyword", + }); + + argv_config.parseArgFromCmd(argv); + + return argv_config.get_result(); + } + + call(argv) { + sessionUtils.argv = argv; + chainMgr.getChainHead().filterProblems(argv, function (e, problems) { + if (e) return reply.info(e); + let new_objcet: Array= []; + problems.forEach((element) => { + let temp_ele: any = {}; + for (const key in element) { + if (key != "link") { + temp_ele[key] = element[key]; + } + } + new_objcet.push(temp_ele); + }); + reply.info(JSON.stringify(new_objcet)); + }); + } +} + +export const listApi: ListApi = new ListApi(); diff --git a/src/rpc/factory/api/pluginApi.ts b/src/rpc/factory/api/pluginApi.ts new file mode 100644 index 0000000..7712132 --- /dev/null +++ b/src/rpc/factory/api/pluginApi.ts @@ -0,0 +1,82 @@ +/* + * Filename: /home/cc/vscode-leetcode-problem-rating/src/rpc/factory/api/pluginApi.ts + * Path: /home/cc/vscode-leetcode-problem-rating + * Created Date: Thursday, November 17th 2022, 11:44:14 am + * Author: ccagml + * + * Copyright (c) 2022 ccagml . All rights reserved. + */ + +import { configUtils } from "../../utils/configUtils"; +import { reply } from "../../utils/ReplyUtils"; +import { chainMgr } from "../../actionChain/chainManager"; +import { sessionUtils } from "../../utils/sessionUtils"; +import { ApiBase } from "../apiBase"; + +class PluginApi extends ApiBase { + constructor() { + super(); + } + + callArg(argv) { + let argv_config = this.api_argv() + .option("d", { + alias: "disable", + type: "boolean", + describe: "Disable plugin", + default: false, + }) + .option("e", { + alias: "enable", + type: "boolean", + describe: "Enable plugin", + default: false, + }) + .option("i", { + alias: "install", + type: "boolean", + describe: "Install plugin", + default: false, + }) + .positional("name", { + type: "string", + describe: "Filter plugin by name", + default: "", + }); + + argv_config.parseArgFromCmd(argv); + + return argv_config.get_result(); + } + + call(argv) { + sessionUtils.argv = argv; + + let all_plugin = chainMgr.installed; + const name = argv.name; + + if (name) { + all_plugin = all_plugin.filter((x) => x.name === name); + } + if (all_plugin.length === 0) { + return reply.fatal("Plugin not found!"); + } + + const p = all_plugin[0]; + if (argv.enable) { + p.enabled = true; + p.save(); + } else if (argv.disable) { + p.enabled = false; + p.save(); + } else if (argv.delete) { + // p.delete(); + p.save(); + chainMgr.init(undefined); + } else if (argv.config) { + reply.info(JSON.stringify(configUtils.plugins[name] || {}, null, 2)); + } + } +} + +export const pluginApi: PluginApi = new PluginApi(); diff --git a/src/rpc/factory/api/queryApi.ts b/src/rpc/factory/api/queryApi.ts new file mode 100644 index 0000000..a568079 --- /dev/null +++ b/src/rpc/factory/api/queryApi.ts @@ -0,0 +1,93 @@ +/* + * Filename: /home/cc/vscode-leetcode-problem-rating/src/rpc/factory/api/queryApi.ts + * Path: /home/cc/vscode-leetcode-problem-rating + * Created Date: Thursday, November 17th 2022, 11:44:14 am + * Author: ccagml + * + * Copyright (c) 2022 ccagml . All rights reserved. + */ + +import { reply } from "../../utils/ReplyUtils"; +import { sessionUtils } from "../../utils/sessionUtils"; +import { ApiBase } from "../apiBase"; + +import { chainMgr } from "../../actionChain/chainManager"; + +class QueryApi extends ApiBase { + constructor() { + super(); + } + callArg(argv) { + let argv_config = this.api_argv() + .option("T", { + alias: "dontTranslate", + type: "boolean", + default: false, + describe: "Set to true to disable endpoint's translation", + }) + .option("a", { + alias: "getTodayQuestion", + type: "boolean", + default: false, + describe: "getTodayQuestion", + }) + .option("b", { + alias: "username", + type: "string", + default: "", + describe: "user name", + }) + .option("c", { + alias: "getRating", + type: "boolean", + default: false, + describe: "ranking", + }) + .option("z", { + alias: "test", + type: "string", + default: "", + describe: "test", + }); + argv_config.parseArgFromCmd(argv); + return argv_config.get_result(); + } + + call(argv) { + sessionUtils.argv = argv; + if (argv.a) { + chainMgr.getChainHead().getTodayQuestion(function (e, result) { + if (e) return; + reply.info(JSON.stringify(result)); + }); + } else if (argv.b) { + chainMgr.getChainHead().getUserContest(argv.b, function (e, result) { + if (e) return; + reply.info(JSON.stringify(result)); + }); + } else if (argv.c) { + chainMgr.getChainHead().getRating(function (e, result) { + if (e) { + let log_data = { + code: 101, + data: {}, + }; + reply.info(JSON.stringify(log_data)); + return; + } + let log_data = { + code: 100, + data: result, + }; + reply.info(JSON.stringify(log_data)); + }); + } else if (argv.z) { + chainMgr.getChainHead().getQueryZ(argv.z, function (e, result) { + if (e) return; + reply.info(JSON.stringify(result)); + }); + } + } +} + +export const queryApi: QueryApi = new QueryApi(); diff --git a/src/rpc/factory/api/showApi.ts b/src/rpc/factory/api/showApi.ts new file mode 100644 index 0000000..3ef7823 --- /dev/null +++ b/src/rpc/factory/api/showApi.ts @@ -0,0 +1,204 @@ +/* + * Filename: /home/cc/vscode-leetcode-problem-rating/src/rpc/factory/api/showApi.ts + * Path: /home/cc/vscode-leetcode-problem-rating + * Created Date: Thursday, November 17th 2022, 11:44:14 am + * Author: ccagml + * + * Copyright (c) 2022 ccagml . All rights reserved. + */ + +let util = require("util"); +let childProcess = require("child_process"); + +import { storageUtils } from "../../utils/storageUtils"; + +import { reply } from "../../utils/ReplyUtils"; +import { configUtils } from "../../utils/configUtils"; + +import { sessionUtils } from "../../utils/sessionUtils"; +import { ApiBase } from "../apiBase"; +import { chainMgr } from "../../actionChain/chainManager"; + +class ShowApi extends ApiBase { + constructor() { + super(); + } + + callArg(argv) { + let argv_config = this.api_argv() + .option("c", { + alias: "codeonly", + type: "boolean", + default: false, + describe: "Only show code template", + }) + .option("e", { + alias: "editor", + type: "string", + describe: "Open source code in editor", + }) + .option("g", { + alias: "gen", + type: "boolean", + default: false, + describe: "Generate source code", + }) + .option("l", { + alias: "lang", + type: "string", + default: configUtils.code.lang, + describe: "Programming language of the source code", + choices: configUtils.sys.langs, + }) + .option("o", { + alias: "outdir", + type: "string", + describe: "Where to save source code", + default: ".", + }) + .option("q", { + alias: "query", + type: "string", + default: "", + describe: [ + "Filter questions by condition:", + "Uppercase means negative", + "e = easy E = m+h", + "m = medium M = e+h", + "h = hard H = e+m", + "d = done D = not done", + "l = locked L = non locked", + "s = starred S = not starred", + ].join("\n"), + }) + .option("t", { + alias: "tag", + type: "array", + default: [], + describe: "Filter questions by tag", + }) + .option("x", { + alias: "extra", + type: "boolean", + default: false, + describe: "Show extra question details in source code", + }) + .option("T", { + alias: "dontTranslate", + type: "boolean", + default: false, + describe: "Set to true to disable endpoint's translation", + }) + .positional("keyword", { + type: "string", + default: "", + describe: "Show question by name or id", + }); + argv_config.parseArgFromCmd(argv); + return argv_config.get_result(); + } + genFileName(problem, opts) { + const path = require("path"); + const params = [storageUtils.fmt(configUtils.file.show, problem), "", storageUtils.getFileExtByLanguage(opts.lang)]; + + // try new name to avoid overwrite by mistake + for (let i = 0; ; ++i) { + const name = path.join(opts.outdir, params.join(".").replace(/\.+/g, ".")); + if (!storageUtils.exist(name)) return name; + params[1] = i; + } + } + + showProblem(problem, argv) { + const taglist = [problem.category] + .concat(problem.companies || []) + .concat(problem.tags || []) + .map((x) => " " + x + " ") + .join(" "); + const langlist = problem.templates + .map((x) => " " + x.value + " ") + .sort() + .join(" "); + + let code; + const needcode = argv.gen || argv.codeonly; + if (needcode) { + const template = problem.templates.find((x) => x.value === argv.lang); + if (!template) { + reply.info('Not supported language "' + argv.lang + '"'); + reply.warn("Supported languages: " + langlist); + return; + } + + const opts = { + lang: argv.lang, + code: template.defaultCode, + tpl: argv.extra ? "detailed" : "codeonly", + }; + code = chainMgr.getChainHead().exportProblem(problem, opts); + } + + let filename; + if (argv.gen) { + storageUtils.mkdir(argv.outdir); + filename = this.genFileName(problem, argv); + storageUtils.write(filename, code); + + if (argv.editor !== undefined) { + childProcess.spawn(argv.editor || configUtils.code.editor, [filename], { + // in case your editor of choice is vim or emacs + stdio: "inherit", + }); + } + } else { + if (argv.codeonly) { + reply.info(code); + return; + } + } + + reply.info(`[${problem.fid}] ${problem.name}`); + reply.info(); + reply.info(problem.link); + if (argv.extra) { + reply.info(); + reply.info("Tags: " + taglist); + reply.info(); + reply.info("Langs: " + langlist); + } + + reply.info(); + reply.info(`* ${problem.category}`); + reply.info(`* ${problem.level} (${problem.percent.toFixed(2)}%)`); + + if (problem.likes) reply.info(`* Likes: ${problem.likes}`); + if (problem.dislikes) reply.info(`* Dislikes: ${problem.dislikes}`); + else reply.info(`* Dislikes: -`); + if (problem.totalAC) reply.info(`* Total Accepted: ${problem.totalAC}`); + if (problem.totalSubmit) reply.info(`* Total Submissions: ${problem.totalSubmit}`); + if (problem.testable && problem.testcase) { + let testcase_value = util.inspect(problem.testcase); + reply.info(`* Testcase Example: ${testcase_value}`); + } + if (filename) reply.info(`* Source Code: ${filename}`); + + reply.info(); + reply.info(problem.desc); + } + + call(argv) { + let that = this; + sessionUtils.argv = argv; + if (argv.keyword.length > 0) { + // show specific one + chainMgr.getChainHead().getProblem(argv.keyword, !argv.dontTranslate, function (e, problem) { + if (e) return reply.info(e); + that.showProblem(problem, argv); + }); + } else { + // + } + } +} + +export const showApi: ShowApi = new ShowApi(); diff --git a/src/rpc/factory/api/starApi.ts b/src/rpc/factory/api/starApi.ts new file mode 100644 index 0000000..69bdc7c --- /dev/null +++ b/src/rpc/factory/api/starApi.ts @@ -0,0 +1,55 @@ +/* + * Filename: /home/cc/vscode-leetcode-problem-rating/src/rpc/factory/api/starApi.ts + * Path: /home/cc/vscode-leetcode-problem-rating + * Created Date: Thursday, November 17th 2022, 11:44:14 am + * Author: ccagml + * + * Copyright (c) 2022 ccagml . All rights reserved. + */ + +import { reply } from "../../utils/ReplyUtils"; + +import { sessionUtils } from "../../utils/sessionUtils"; +import { ApiBase } from "../apiBase"; +import { chainMgr } from "../../actionChain/chainManager"; + +class StarApi extends ApiBase { + constructor() { + super(); + } + + callArg(argv) { + let argv_config = this.api_argv() + .option("d", { + alias: "delete", + type: "boolean", + describe: "Unstar question", + default: false, + }) + .positional("keyword", { + type: "string", + describe: "Question name or id", + default: "", + }); + + argv_config.parseArgFromCmd(argv); + + return argv_config.get_result(); + } + + call(argv) { + sessionUtils.argv = argv; + // translation doesn't affect question lookup + chainMgr.getChainHead().getProblem(argv.keyword, true, function (e, problem) { + if (e) return reply.info(e); + + chainMgr.getChainHead().starProblem(problem, !argv.delete, function (e, starred) { + if (e) return reply.info(e); + reply.info(`[${problem.fid}] ${problem.name} ${starred ? "icon.like" : "icon.unlike"}`); + chainMgr.getChainHead().updateProblem(problem, { starred: starred }); + }); + }); + } +} + +export const starApi: StarApi = new StarApi(); diff --git a/src/childProcessCall/commands/submission.ts b/src/rpc/factory/api/submissionApi.ts similarity index 88% rename from src/childProcessCall/commands/submission.ts rename to src/rpc/factory/api/submissionApi.ts index f0ff5ef..98b2684 100644 --- a/src/childProcessCall/commands/submission.ts +++ b/src/rpc/factory/api/submissionApi.ts @@ -1,36 +1,29 @@ /* - * Filename: https://github.com/ccagml/vscode-leetcode-problem-rating/src/childProcessCall/commands/submission.ts - * Path: https://github.com/ccagml/vscode-leetcode-problem-rating - * Created Date: Thursday, October 27th 2022, 7:43:29 pm + * Filename: /home/cc/vscode-leetcode-problem-rating/src/rpc/factory/api/submission.ts + * Path: /home/cc/vscode-leetcode-problem-rating + * Created Date: Monday, November 14th 2022, 4:04:31 pm * Author: ccagml * * Copyright (c) 2022 ccagml . All rights reserved. */ - - // let path = require('path'); // let _ = require('underscore'); - - -// import { helper } from "../helper"; +// import { commUtils } from "../commUtils"; // import { file } from "../file"; // import { config } from "../config"; // import { log } from "../log"; // import { Queue } from "../queue"; // import { corePlugin } from "../core"; -// import { session } from "../session"; - +// import { sessionUtils } from "../session"; class SubMission { - constructor() { + constructor() {} - } - - // process_argv = function (argv) { - // let argv_config = helper.base_argv().option('a', { + // callArg = function (argv) { + // let argv_config = this.api_argv().option('a', { // alias: 'all', // type: 'boolean', // default: false, @@ -65,12 +58,11 @@ class SubMission { // default: '', // describe: 'Download specific question by id' // }); - // argv_config.process_argv(argv); + // argv_config.parseArgFromCmd(argv); // return argv_config.get_result(); // }; - // doTask(problem, queue, cb) { // let that = this; // const argv = queue.ctx.argv; @@ -116,7 +108,7 @@ class SubMission { // data.sid = submission.id; // data.ac = submission.ac ? 'ac' : 'notac'; // const basename = storageUtils.fmt(config.storageUtils.submission, data); - // const f = path.join(argv.outdir, basename + helper.langToExt(submission.lang)); + // const f = path.join(argv.outdir, basename + storageUtils.getFileExtByLanguage(submission.lang)); // storageUtils.mkdir(argv.outdir); // // skip the existing cached submissions @@ -161,6 +153,4 @@ class SubMission { // }; } - - export const subMissionCommand: SubMission = new SubMission(); diff --git a/src/rpc/factory/api/submitApi.ts b/src/rpc/factory/api/submitApi.ts new file mode 100644 index 0000000..2d796f8 --- /dev/null +++ b/src/rpc/factory/api/submitApi.ts @@ -0,0 +1,133 @@ +/* + * Filename: /home/cc/vscode-leetcode-problem-rating/src/rpc/factory/api/submitApi.ts + * Path: /home/cc/vscode-leetcode-problem-rating + * Created Date: Thursday, November 17th 2022, 11:44:14 am + * Author: ccagml + * + * Copyright (c) 2022 ccagml . All rights reserved. + */ + +let util = require("util"); +let lodash = require("lodash"); + +import { storageUtils } from "../../utils/storageUtils"; +import { reply } from "../../utils/ReplyUtils"; + +import { sessionUtils } from "../../utils/sessionUtils"; +import { ApiBase } from "../apiBase"; +import { chainMgr } from "../../actionChain/chainManager"; + +class SubmitApi extends ApiBase { + constructor() { + super(); + } + + callArg(argv) { + let argv_config = this.api_argv().positional("filename", { + type: "string", + describe: "Code file to submit", + default: "", + }); + argv_config.parseArgFromCmd(argv); + + return argv_config.get_result(); + } + + printResult(actual, k, log_obj) { + if (!actual.hasOwnProperty(k)) return; + + const v = actual[k] || ""; + const lines = Array.isArray(v) ? v : [v]; + for (let line of lines) { + if (k !== "state") { + if (!log_obj.hasOwnProperty(lodash.startCase(k))) { + log_obj[lodash.startCase(k)] = [line]; + } else { + log_obj[lodash.startCase(k)].push(line); + } + } else { + log_obj.messages.push(line); + } + } + } + + printLine(log_obj, ...ret: any[]) { + const args = ret.slice(1); + const line = util.format.apply(util, args); + log_obj.messages.push(line); + } + + call(argv) { + sessionUtils.argv = argv; + if (!storageUtils.exist(argv.filename)) return reply.fatal("File " + argv.filename + " not exist!"); + + const meta = storageUtils.meta(argv.filename); + let that = this; + // translation doesn't affect problem lookup + chainMgr.getChainHead().getProblem(meta, true, function (e, problem) { + if (e) return reply.info(e); + + problem.file = argv.filename; + problem.lang = meta.lang; + + chainMgr.getChainHead().submitProblem(problem, function (e, results) { + if (e) return reply.info(e); + + const result = results[0]; + + let log_obj: any = {}; + log_obj.messages = []; + log_obj.system_message = {}; + log_obj.system_message.fid = problem.fid; + log_obj.system_message.id = problem.id; + log_obj.system_message.qid = problem.id; + log_obj.system_message.sub_type = "submit"; + log_obj.system_message.accepted = false; + + that.printResult(result, "state", log_obj); + that.printLine(log_obj, result, "%d/%d cases passed (%s)", result.passed, result.total, result.runtime); + + if (result.ok) { + sessionUtils.updateStat("ac", 1); + sessionUtils.updateStat("ac.set", problem.fid); + log_obj.system_message.accepted = true; + + (function () { + if (result.runtime_percentile) + that.printLine( + log_obj, + result, + "Your runtime beats %d %% of %s submissions", + result.runtime_percentile.toFixed(2), + result.lang + ); + else return reply.warn("Failed to get runtime percentile."); + if (result.memory && result.memory_percentile) + that.printLine( + log_obj, + result, + "Your memory usage beats %d %% of %s submissions (%s)", + result.memory_percentile.toFixed(2), + result.lang, + result.memory + ); + else return reply.warn("Failed to get memory percentile."); + })(); + } else { + result.testcase = result.testcase.slice(1, -1).replace(/\\n/g, "\n"); + that.printResult(result, "error", log_obj); + that.printResult(result, "testcase", log_obj); + that.printResult(result, "answer", log_obj); + that.printResult(result, "expected_answer", log_obj); + that.printResult(result, "stdout", log_obj); + } + reply.info(JSON.stringify(log_obj)); + chainMgr.getChainHead().updateProblem(problem, { + state: result.ok ? "ac" : "notac", + }); + }); + }); + } +} + +export const submitApi: SubmitApi = new SubmitApi(); diff --git a/src/rpc/factory/api/testApi.ts b/src/rpc/factory/api/testApi.ts new file mode 100644 index 0000000..3f351c1 --- /dev/null +++ b/src/rpc/factory/api/testApi.ts @@ -0,0 +1,200 @@ +/* + * Filename: /home/cc/vscode-leetcode-problem-rating/src/rpc/factory/api/testApi.ts + * Path: /home/cc/vscode-leetcode-problem-rating + * Created Date: Thursday, November 17th 2022, 11:44:14 am + * Author: ccagml + * + * Copyright (c) 2022 ccagml . All rights reserved. + */ + +let _ = require("underscore"); +let lodash = require("lodash"); + +import { storageUtils } from "../../utils/storageUtils"; +import { reply } from "../../utils/ReplyUtils"; + +import { sessionUtils } from "../../utils/sessionUtils"; +import { ApiBase } from "../apiBase"; +import { commUtils } from "../../utils/commUtils"; +import { chainMgr } from "../../actionChain/chainManager"; + +class TestApi extends ApiBase { + constructor() { + super(); + } + + callArg(argv) { + let argv_config = this.api_argv() + .option("i", { + alias: "interactive", + type: "boolean", + default: false, + describe: "Provide test case interactively", + }) + .option("t", { + alias: "testcase", + type: "string", + default: "", + describe: "Provide test case", + }) + .option("a", { + alias: "allcase", + type: "boolean", + default: false, + describe: "Provide all test case", + }) + .positional("filename", { + type: "string", + default: "", + describe: "Code file to test", + }); + + argv_config.parseArgFromCmd(argv); + + return argv_config.get_result(); + } + + printResult(actual, extra, k, log_obj) { + if (!actual.hasOwnProperty(k)) return; + // HACk: leetcode still return 'Accepted' even the answer is wrong!! + const v = actual[k] || ""; + if (k === "state" && v === "Accepted") return; + + // let ok = actual.ok; + + const lines = Array.isArray(v) ? v : [v]; + for (let line of lines) { + const extraInfo = extra ? ` (${extra})` : ""; + if (k !== "state") { + let new_kk = lodash.startCase(k) + extraInfo; + if (!log_obj.hasOwnProperty(new_kk)) { + log_obj[new_kk] = [line]; + } else { + log_obj[new_kk].push(line); + } + } else { + log_obj.messages.push(line); + } + } + } + + runTest(argv) { + let that = this; + if (!storageUtils.exist(argv.filename)) return reply.fatal("File " + argv.filename + " not exist!"); + + const meta = storageUtils.meta(argv.filename); + + // [key: string]: string[]; + // messages: string[]; + + chainMgr.getChainHead().getProblem(meta, true, function (e, problem) { + if (e) + return reply.info( + JSON.stringify({ + messages: ["error"], + code: [-1], + error: [e.msg || e], + }) + ); + + if (!problem.testable) + return reply.info( + JSON.stringify({ + messages: ["error"], + code: [-2], + error: ["not testable? please submit directly!"], + }) + ); + + if (argv.testcase) { + problem.testcase = argv.testcase.replace(/\\n/g, "\n"); + } + + if (argv.allcase) { + let temp_test_set: Set = new Set(); + + let new_desc = problem.desc; + let calcCaseList = storageUtils.getAllCase(new_desc); + calcCaseList.forEach((x) => { + let xxx = x.join("\n"); + temp_test_set.add(xxx); + }); + if (meta.writeCase) { + meta.writeCase.forEach((xxx) => { + temp_test_set.add(xxx); + }); + } + + let temp_test: Array = []; + temp_test_set.forEach((x) => { + temp_test.push(x); + }); + + let all_case = temp_test.join("\n"); + problem.testcase = all_case; + } + + if (!problem.testcase) + return reply.info( + JSON.stringify({ + messages: ["error"], + code: [-3], + error: ["missing testcase?"], + }) + ); + + problem.file = argv.filename; + problem.lang = meta.lang; + + chainMgr.getChainHead().testProblem(problem, function (e, results) { + if (e) return reply.info(JSON.stringify(e)); + + results = _.sortBy(results, (x) => x.type); + + let log_obj: any = {}; + log_obj.messages = []; + log_obj.system_message = {}; + log_obj.system_message.fid = problem.fid; + log_obj.system_message.id = problem.id; + log_obj.system_message.qid = problem.id; + log_obj.system_message.sub_type = "test"; + log_obj.system_message.accepted = false; + + if (results[0].state === "Accepted") { + results[0].state = "Finished"; + log_obj.system_message.accepted = true; + } + that.printResult(results[0], null, "state", log_obj); + that.printResult(results[0], null, "error", log_obj); + + results[0].your_input = problem.testcase; + results[0].output = results[0].answer; + // LeetCode-CN returns the actual and expected answer into two separate responses + if (results[1]) { + results[0].expected_answer = results[1].answer; + } + results[0].stdout = results[0].stdout.slice(1, -1).replace(/\\n/g, "\n"); + that.printResult(results[0], null, "your_input", log_obj); + that.printResult(results[0], results[0].runtime, "output", log_obj); + that.printResult(results[0], null, "expected_answer", log_obj); + that.printResult(results[0], null, "stdout", log_obj); + reply.info(JSON.stringify(log_obj)); + }); + }); + } + + call(argv) { + let that = this; + sessionUtils.argv = argv; + if (!argv.i) return that.runTest(argv); + + commUtils.readStdin(function (e, data) { + if (e) return reply.info(e); + + argv.testcase = data; + return that.runTest(argv); + }); + } +} + +export const testApi: TestApi = new TestApi(); diff --git a/src/rpc/factory/api/userApi.ts b/src/rpc/factory/api/userApi.ts new file mode 100644 index 0000000..ab9a3d7 --- /dev/null +++ b/src/rpc/factory/api/userApi.ts @@ -0,0 +1,150 @@ +/* + * Filename: /home/cc/vscode-leetcode-problem-rating/src/rpc/factory/api/userApi.ts + * Path: /home/cc/vscode-leetcode-problem-rating + * Created Date: Thursday, November 17th 2022, 11:44:14 am + * Author: ccagml + * + * Copyright (c) 2022 ccagml . All rights reserved. + */ + +let prompt_out = require("prompt"); + +import { reply } from "../../utils/ReplyUtils"; + +import { sessionUtils } from "../../utils/sessionUtils"; +import { ApiBase } from "../apiBase"; + +import { chainMgr } from "../../actionChain/chainManager"; + +class UserApi extends ApiBase { + constructor() { + super(); + } + + callArg(argv) { + let argv_config = this.api_argv() + .option("l", { + alias: "login", + type: "boolean", + default: false, + describe: "Login", + }) + .option("c", { + alias: "cookie", + type: "boolean", + default: false, + describe: "cookieLogin", + }) + .option("g", { + alias: "github", + type: "boolean", + default: false, + describe: "githubLogin", + }) + .option("i", { + alias: "linkedin", + type: "boolean", + default: false, + describe: "linkedinLogin", + }) + .option("L", { + alias: "logout", + type: "boolean", + default: false, + describe: "Logout", + }); + + argv_config.parseArgFromCmd(argv); + + return argv_config.get_result(); + } + + call(argv) { + sessionUtils.argv = argv; + let user: any = null; + if (argv.login) { + // login + prompt_out.colors = false; + prompt_out.message = ""; + prompt_out.start(); + prompt_out.get( + [ + { name: "login", required: true }, + { name: "pass", required: true, hidden: true }, + ], + function (e, user) { + if (e) { + return reply.info(JSON.stringify({ code: -1, msg: e.msg || e })); + } + + chainMgr.getChainHead().login(user, function (e, user) { + if (e) { + return reply.info(JSON.stringify({ code: -2, msg: e.msg || e })); + } + reply.info(JSON.stringify({ code: 100, user_name: user.name })); + }); + } + ); + } else if (argv.logout) { + // logout + user = chainMgr.getChainHead().logout(user, true); + if (user) reply.info(JSON.stringify({ code: 100, user_name: user.name })); + else reply.info(JSON.stringify({ code: -3, msg: "You are not login yet?" })); + // third parties + } else if (argv.github || argv.linkedin) { + // add future third parties here + const functionMap = new Map([ + ["g", chainMgr.getChainHead().githubLogin], + ["github", chainMgr.getChainHead().githubLogin], + ["i", chainMgr.getChainHead().linkedinLogin], + ["linkedin", chainMgr.getChainHead().linkedinLogin], + ]); + const keyword = Object.entries(argv).filter((i) => i[1] === true)[0][0]; + const coreFunction = functionMap.get(keyword); + if (coreFunction) { + prompt_out.colors = false; + prompt_out.message = ""; + prompt_out.start(); + prompt_out.get( + [ + { name: "login", required: true }, + { name: "pass", required: true, hidden: true }, + ], + function (e, user) { + if (e) return reply.info(JSON.stringify({ code: -4, msg: e.msg || e })); + coreFunction(user, function (e, user) { + if (e) return reply.info(JSON.stringify({ code: -5, msg: e.msg || e })); + reply.info(JSON.stringify({ code: 100, user_name: user.name })); + }); + } + ); + } + } else if (argv.cookie) { + // session + prompt_out.colors = false; + prompt_out.message = ""; + prompt_out.start(); + prompt_out.get( + [ + { name: "login", required: true }, + { name: "cookie", required: true }, + ], + function (e, user) { + if (e) return reply.info(e); + chainMgr.getChainHead().cookieLogin(user, function (e, user) { + if (e) return reply.info(JSON.stringify({ code: -6, msg: e.msg || e })); + reply.info(JSON.stringify({ code: 100, user_name: user.name })); + }); + } + ); + } else { + // show current user + user = sessionUtils.getUser(); + if (user) { + reply.info(JSON.stringify({ code: 100, user_name: user.name })); + } else return reply.info(JSON.stringify({ code: -7, msg: "You are not login yet?" })); + } + } +} + +export const userApi: UserApi = new UserApi(); diff --git a/src/rpc/factory/apiBase.ts b/src/rpc/factory/apiBase.ts new file mode 100644 index 0000000..7b22632 --- /dev/null +++ b/src/rpc/factory/apiBase.ts @@ -0,0 +1,97 @@ +/* + * Filename: /home/cc/vscode-leetcode-problem-rating/src/rpc/factory/apiBase.ts + * Path: /home/cc/vscode-leetcode-problem-rating + * Created Date: Thursday, November 17th 2022, 11:44:14 am + * Author: ccagml + * + * Copyright (c) 2022 ccagml . All rights reserved. + */ + +export interface IApi { + callArg(arg); + call(arg): void; +} + +export class ApiBase implements IApi { + constructor() {} + callArg(arg: any) { + console.log("未实现callArg", arg); + } + call(arg: any) { + console.log("未实现call", arg); + } + api_argv() { + let base = { + all_base_data: {}, + positional_index: 0, + positional_key: {}, + option: function (key, value) { + this.all_base_data[key] = value.default; + this.all_base_data[value.alias] = value.default; + this[key] = value; + return this; + }, + positional: function (key, value) { + this.positional_key[this.positional_index] = key; + this.positional_index = this.positional_index + 1; + this.all_base_data[key] = value.default; + this.all_base_data[value.alias] = value.default; + this[key] = value; + return this; + }, + set_opt(key, temp_val?) { + let cfg = this[key]; + if (cfg) { + if (cfg.type == "boolean") { + this.all_base_data[key] = true; + if (cfg.alias) { + this.all_base_data[cfg.alias] = true; + } + return false; + } else { + this.all_base_data[key] = temp_val; + if (cfg.alias) { + this.all_base_data[cfg.alias] = temp_val; + } + return true; + } + } else { + this.all_base_data[key] = true; + } + return false; + }, + set_posi(value, index) { + let cfg_key = this.positional_key[index]; + let cfg = this[cfg_key]; + if (cfg) { + this.all_base_data[cfg_key] = value; + if (cfg.alias) { + this.all_base_data[cfg.alias] = value; + } + } + }, + parseArgFromCmd(argv) { + let all_posi = 0; + for (let index = 3; index < argv.length; index++) { + let con = argv[index]; + if (con[0] == "-" && con[1] == "-") { + this.set_opt(con.substring(2)); + } else if (con[0] == "-") { + for (let con_index = 1; con_index < con.length; con_index++) { + if (this.set_opt(con[con_index], argv[index + 1])) { + con_index++; + } + } + } else { + this.set_posi(con, all_posi); + all_posi = all_posi + 1; + } + } + }, + get_result: function () { + return this.all_base_data; + }, + }; + return base; + } +} diff --git a/src/rpc/factory/apiFactory.ts b/src/rpc/factory/apiFactory.ts new file mode 100644 index 0000000..065defe --- /dev/null +++ b/src/rpc/factory/apiFactory.ts @@ -0,0 +1,37 @@ +import { cacheApi } from "./api/cacheApi"; +import { listApi } from "./api/listApi"; +import { pluginApi } from "./api/pluginApi"; +import { queryApi } from "./api/queryApi"; +import { showApi } from "./api/showApi"; +import { starApi } from "./api/starApi"; +import { submitApi } from "./api/submitApi"; +import { testApi } from "./api/testApi"; +import { userApi } from "./api/userApi"; +import { IApi } from "./apiBase"; + +class ApiFactory { + constructor() {} + getApi(api: string): IApi | undefined { + if (api == "cache") { + return cacheApi; + } else if (api == "list") { + return listApi; + } else if (api == "plugin") { + return pluginApi; + } else if (api == "query") { + return queryApi; + } else if (api == "show") { + return showApi; + } else if (api == "star") { + return starApi; + } else if (api == "submit") { + return submitApi; + } else if (api == "test") { + return testApi; + } else if (api == "user") { + return userApi; + } + return undefined; + } +} +export const apiFactory: ApiFactory = new ApiFactory(); diff --git a/src/rpc/utils/ReplyUtils.ts b/src/rpc/utils/ReplyUtils.ts new file mode 100644 index 0000000..aca9f6e --- /dev/null +++ b/src/rpc/utils/ReplyUtils.ts @@ -0,0 +1,62 @@ +/* + * Filename: /home/cc/vscode-leetcode-problem-rating/src/rpc/Response.ts + * Path: /home/cc/vscode-leetcode-problem-rating + * Created Date: Monday, November 14th 2022, 4:04:31 pm + * Author: ccagml + * + * Copyright (c) 2022 ccagml . All rights reserved. + */ + +let _ = require("underscore"); + +class Reply { + output = _.bind(console.log, console); + level: any; + levels = new Map([ + ["INFO", { value: 2 }], + ["WARN", { value: 3 }], + ["ERROR", { value: 4 }], + ]); + setLevel(name: any) { + this.level = this.levels.get(name) || this.levels.get("INFO"); + } + + fail(e: any) { + let msg = e.msg || e; + if (e.statusCode) { + msg += " [code=" + e.statusCode + "]"; + } + this.error(msg); + } + + fatal(e: any) { + this.error(e); + process.exit(1); + } + + init() { + this.setLevel("INFO"); + } + + info(...rest: any[]) { + const args = rest; //Array.from(arguments); + let s = args.map((x) => x.toString()).join(" "); + this.output(s); + } + warn(...rest: any[]) { + const args = rest; //Array.from(arguments); + args.unshift("[" + "warn" + "]"); + + let s = args.map((x) => x.toString()).join(" "); + this.output(s); + } + error(...rest: any[]) { + const args = rest; //Array.from(arguments); + args.unshift("[" + "error" + "]"); + + let s = args.map((x) => x.toString()).join(" "); + this.output(s); + } +} + +export const reply: Reply = new Reply(); diff --git a/src/rpc/utils/commUtils.ts b/src/rpc/utils/commUtils.ts new file mode 100644 index 0000000..d895b3c --- /dev/null +++ b/src/rpc/utils/commUtils.ts @@ -0,0 +1,86 @@ +/* + * Filename: /home/cc/vscode-leetcode-problem-rating/src/rpc/commUtils.ts + * Path: /home/cc/vscode-leetcode-problem-rating + * Created Date: Wednesday, November 16th 2022, 4:50:55 pm + * Author: ccagml + * + * Copyright (c) 2022 ccagml . All rights reserved. + */ + +import { storageUtils } from "./storageUtils"; + +class CommUtils { + KEYS; + constructor() { + this.KEYS = { + user: "../user", + stat: "../stat", + plugins: "../../plugins", + problems: "problems", + translation: "translationConfig", + ranting_path: "../../rating", + problem: (p) => p.fid + "." + p.slug + "." + p.category, + }; + } + + getNameByLevel(level: any) { + switch (level) { + case 1: + return "Easy"; + case 2: + return "Medium"; + case 3: + return "Hard"; + default: + return " "; + } + } + + readStdin(cb) { + const stdin = process.stdin; + let bufs: Array = []; + + console.log( + "NOTE: to finish the input, press " + (storageUtils.isWindows() ? " and " : " ") + ); + + stdin.on("readable", function () { + const data = stdin.read(); + if (data) { + // windows doesn't treat ctrl-D as EOF + if (storageUtils.isWindows() && data.toString() === "\x04\r\n") { + stdin.emit("end"); + } else { + bufs.push(data); + } + } + }); + stdin.on("end", function () { + cb(null, Buffer.concat(bufs).toString()); + }); + stdin.on("error", cb); + } + + getSetCookieValue(resp: any, key: any) { + const cookies = resp.headers["set-cookie"]; + if (!cookies) return null; + + for (let i = 0; i < cookies.length; ++i) { + const sections = cookies[i].split(";"); + for (let j = 0; j < sections.length; ++j) { + const kv = sections[j].trim().split("="); + if (kv[0] === key) return kv[1]; + } + } + return null; + } + + printSafeHTTP(msg: any) { + return msg + .replace(/(Cookie\s*:\s*)'.*?'/, "$1 ") + .replace(/('X-CSRFToken'\s*:\s*)'.*?'/, "$1 ") + .replace(/('set-cookie'\s*:\s*)\[.*?\]/, "$1 "); + } +} + +export const commUtils: CommUtils = new CommUtils(); diff --git a/src/rpc/utils/configUtils.ts b/src/rpc/utils/configUtils.ts new file mode 100644 index 0000000..6c829a9 --- /dev/null +++ b/src/rpc/utils/configUtils.ts @@ -0,0 +1,140 @@ +/* + * Filename: https://github.com/ccagml/vscode-leetcode-problem-rating/src/rpc/config.ts + * Path: https://github.com/ccagml/vscode-leetcode-problem-rating + * Created Date: Thursday, October 27th 2022, 7:43:29 pm + * Author: ccagml + * + * Copyright (c) 2022 ccagml . All rights reserved. + */ + +let underscore = require("underscore"); + +class Config { + LCPTCTX: any; + app: any; + sys: any; + autologin: any; + code: any; + file: any; + color: any; + icon: any; + network: any; + plugins: any; + constructor() { + this.sys = { + categories: ["algorithms", "LCCI", "LCOF", "LCOF2"], + langs: [ + "bash", + "c", + "cpp", + "csharp", + "golang", + "java", + "javascript", + "kotlin", + "mysql", + "php", + "python", + "python3", + "ruby", + "rust", + "scala", + "swift", + "typescript", + ], + urls: { + // base urls + base: "https://leetcode.com", + graphql: "https://leetcode.com/graphql", + login: "https://leetcode.com/accounts/login/", + // third part login base urls. TODO facebook google + github_login: "https://leetcode.com/accounts/github/login/?next=%2F", + facebook_login: "https://leetcode.com/accounts/facebook/login/?next=%2F", + linkedin_login: "https://leetcode.com/accounts/linkedin_oauth2/login/?next=%2F", + // redirect urls + leetcode_redirect: "https://leetcode.com/", + github_tf_redirect: "https://github.com/sessions/two-factor", + // simulate login urls + github_login_request: "https://github.com/login", + github_session_request: "https://github.com/session", + github_tf_session_request: "https://github.com/sessions/two-factor", + linkedin_login_request: "https://www.linkedin.com/login", + linkedin_session_request: "https://www.linkedin.com/checkpoint/lg/login-submit", + // questions urls + problems: "https://leetcode.com/api/problems/$category/", + problem: "https://leetcode.com/problems/$slug/description/", + test: "https://leetcode.com/problems/$slug/interpret_solution/", + session: "https://leetcode.com/session/", + submit: "https://leetcode.com/problems/$slug/submit/", + submissions: "https://leetcode.com/api/submissions/$slug", + submission: "https://leetcode.com/submissions/detail/$id/", + verify: "https://leetcode.com/submissions/detail/$id/check/", + favorites: "https://leetcode.com/list/api/questions", + favorite_delete: "https://leetcode.com/list/api/questions/$hash/$id", + problem_detail: "", + noj_go: "", + u: "", + }, + }; + + this.autologin = { + enable: false, + retry: 2, + }; + this.code = { + editor: "vim", + lang: "cpp", + }; + this.file = { + show: "${fid}.${slug}", + submission: "${fid}.${slug}.${sid}.${ac}", + }; + this.color = { + enable: true, + theme: "default", + }; + this.icon = { + theme: "", + }; + this.network = { + concurrency: 10, + delay: 1, + }; + this.plugins = {}; + } + + init(ctx) { + this.LCPTCTX = ctx; + } + + getAll(useronly) { + const cfg = underscore.extendOwn({}, this); + if (useronly) delete cfg.sys; + return cfg; + } + + fix_cn() { + this.app = "leetcode.cn"; + this.sys.urls.base = "https://leetcode.cn"; + this.sys.urls.login = "https://leetcode.cn/accounts/login/"; + this.sys.urls.problems = "https://leetcode.cn/api/problems/$category/"; + this.sys.urls.problem = "https://leetcode.cn/problems/$slug/description/"; + this.sys.urls.graphql = "https://leetcode.cn/graphql"; + this.sys.urls.problem_detail = "https://leetcode.cn/graphql"; + this.sys.urls.test = "https://leetcode.cn/problems/$slug/interpret_solution/"; + this.sys.urls.session = "https://leetcode.cn/session/"; + this.sys.urls.submit = "https://leetcode.cn/problems/$slug/submit/"; + this.sys.urls.submissions = "https://leetcode.cn/api/submissions/$slug"; + this.sys.urls.submission = "https://leetcode.cn/submissions/detail/$id/"; + this.sys.urls.verify = "https://leetcode.cn/submissions/detail/$id/check/"; + this.sys.urls.favorites = "https://leetcode.cn/list/api/questions"; + this.sys.urls.favorite_delete = "https://leetcode.cn/list/api/questions/$hash/$id"; + this.sys.urls.noj_go = "https://leetcode.cn/graphql/noj-go/"; + this.sys.urls.u = "https://leetcode.cn/u/$username/"; + this.sys.urls.github_login = "https://leetcode.cn/accounts/github/login/?next=%2F"; + this.sys.urls.linkedin_login = "https://leetcode.cn/accounts/linkedin_oauth2/login/?next=%2F"; + this.sys.urls.leetcode_redirect = "https://leetcode.cn/"; + } +} + +export const configUtils: Config = new Config(); diff --git a/src/childProcessCall/queue.ts b/src/rpc/utils/queueUtils.ts similarity index 71% rename from src/childProcessCall/queue.ts rename to src/rpc/utils/queueUtils.ts index 1db7165..3ff2496 100644 --- a/src/childProcessCall/queue.ts +++ b/src/rpc/utils/queueUtils.ts @@ -1,5 +1,5 @@ /* - * Filename: https://github.com/ccagml/vscode-leetcode-problem-rating/src/childProcessCall/queue.ts + * Filename: https://github.com/ccagml/vscode-leetcode-problem-rating/src/rpc/queue.ts * Path: https://github.com/ccagml/vscode-leetcode-problem-rating * Created Date: Thursday, October 27th 2022, 7:43:29 pm * Author: ccagml @@ -7,11 +7,9 @@ * Copyright (c) 2022 ccagml . All rights reserved. */ +let underscore = require("underscore"); - -let underscore = require('underscore'); - -import { config } from "./config"; +import { configUtils } from "./configUtils"; export class Queue { tasks; @@ -30,28 +28,29 @@ export class Queue { addTask(task) { this.tasks.push(task); return this; - }; + } addTasks(tasks) { this.tasks = this.tasks.concat(tasks); return this; - }; + } run(concurrency?, onDone?) { - this.concurrency = concurrency || config.network.concurrency || 1; + this.concurrency = concurrency || configUtils.network.concurrency || 1; this.onDone = onDone; const self = this; for (let i = 0; i < this.concurrency; ++i) { - setImmediate(function () { self.workerRun(); }); + setImmediate(function () { + self.workerRun(); + }); } - }; + } workerRun() { // no more tasks, quit now if (this.tasks.length === 0) { - if (--this.concurrency === 0 && this.onDone) - this.onDone(this.error, this.ctx); + if (--this.concurrency === 0 && this.onDone) this.onDone(this.error, this.ctx); return; } @@ -61,8 +60,9 @@ export class Queue { if (e) self.error = e; // TODO: could retry failed task here. - setImmediate(function () { self.workerRun(); }); + setImmediate(function () { + self.workerRun(); + }); }); - }; + } } - diff --git a/src/childProcessCall/session.ts b/src/rpc/utils/sessionUtils.ts similarity index 52% rename from src/childProcessCall/session.ts rename to src/rpc/utils/sessionUtils.ts index d1737c3..bd30d67 100644 --- a/src/childProcessCall/session.ts +++ b/src/rpc/utils/sessionUtils.ts @@ -1,5 +1,5 @@ /* - * Filename: https://github.com/ccagml/vscode-leetcode-problem-rating/src/childProcessCall/session.ts + * Filename: https://github.com/ccagml/vscode-leetcode-problem-rating/src/rpc/session.ts * Path: https://github.com/ccagml/vscode-leetcode-problem-rating * Created Date: Thursday, October 27th 2022, 7:43:29 pm * Author: ccagml @@ -7,62 +7,59 @@ * Copyright (c) 2022 ccagml . All rights reserved. */ - -let moment_out = require('moment'); -let underscore = require('underscore'); - +let moment_out = require("moment"); +let underscore = require("underscore"); import { storageUtils } from "./storageUtils"; -import { config } from "./config"; -import { helper } from "./helper"; +import { configUtils } from "./configUtils"; +import { commUtils } from "./commUtils"; class Session { errors = { EXPIRED: { - msg: 'session expired, please login again', - statusCode: -1 - } + msg: "session expired, please login again", + statusCode: -1, + }, }; argv: any = {}; - constructor() { - } + constructor() {} public getUser = function () { - return storageUtils.getCache(helper.KEYS.user); + return storageUtils.getCache(commUtils.KEYS.user); }; public saveUser = function (user) { // when auto login enabled, have to save password to re-login later // otherwise don't dump password for the sake of security. - const _user = underscore.omit(user, config.autologin.enable ? [] : ['pass']); - storageUtils.setCache(helper.KEYS.user, _user); + const _user = underscore.omit(user, configUtils.autologin.enable ? [] : ["pass"]); + storageUtils.setCache(commUtils.KEYS.user, _user); }; public deleteUser = function () { - storageUtils.delCache(helper.KEYS.user); + storageUtils.delCache(commUtils.KEYS.user); }; public deleteCodingSession = function () { - storageUtils.delCache(helper.KEYS.problems); + storageUtils.delCache(commUtils.KEYS.problems); }; public isLogin() { return this.getUser() !== null; - }; + } public updateStat = function (k, v) { // TODO: use other storage if too many stat data - const today = moment_out().format('YYYY-MM-DD'); - const stats = storageUtils.getCache(helper.KEYS.stat) || {}; - const stat = stats[today] = stats[today] || {}; + const today = moment_out().format("YYYY-MM-DD"); + const stats = storageUtils.getCache(commUtils.KEYS.stat) || {}; + const stat = (stats[today] = stats[today] || {}); - if (k.endsWith('.set')) { + if (k.endsWith(".set")) { const s = new Set(stat[k] || []); s.add(v); stat[k] = Array.from(s); } else { stat[k] = (stat[k] || 0) + v; } - storageUtils.setCache(helper.KEYS.stat, stats); + storageUtils.setCache(commUtils.KEYS.stat, stats); }; } -export const session: Session = new Session(); +export const sessionUtils: Session = new Session(); diff --git a/src/rpc/utils/storageUtils.ts b/src/rpc/utils/storageUtils.ts new file mode 100644 index 0000000..19ac433 --- /dev/null +++ b/src/rpc/utils/storageUtils.ts @@ -0,0 +1,486 @@ +/* + * Filename: https://github.com/ccagml/vscode-leetcode-problem-rating/src/rpc/storageUtils.ts + * Path: https://github.com/ccagml/vscode-leetcode-problem-rating + * Created Date: Thursday, October 27th 2022, 7:43:29 pm + * Author: ccagml + * + * Copyright (c) 2022 ccagml . All rights reserved. + */ + +let fs = require("fs"); +let os = require("os"); +let path = require("path"); + +let _ = require("underscore"); +let mkdirp = require("mkdirp"); + +export interface IMETA { + id: string; + fid: string; + lang: string; + writeCase: Array ; +} + +//Object.assign({}, defaultMETA, {}) +export const defaultMETA: IMETA = { + id: "", + fid: "", + lang: "", + writeCase: [], +}; + +class StorageUtils { + public storageFileInfo = { + bash: { + ext: ".sh", + start: "#", + line: "#", + end: "#", + singleLine: "#", + }, + c: { + ext: ".c", + start: "/*", + line: " *", + end: " */", + singleLine: "//", + }, + cpp: { + ext: ".cpp", + start: "/*", + line: " *", + end: " */", + singleLine: "//", + }, + csharp: { + ext: ".cs", + start: "/*", + line: " *", + end: " */", + singleLine: "//", + }, + golang: { + ext: ".go", + start: "/*", + line: " *", + end: " */", + singleLine: "//", + }, + java: { + ext: ".java", + start: "/*", + line: " *", + end: " */", + singleLine: "//", + }, + javascript: { + ext: ".js", + start: "/*", + line: " *", + end: " */", + singleLine: "//", + }, + kotlin: { + ext: ".kt", + start: "/*", + line: " *", + end: " */", + singleLine: "//", + }, + mysql: { + ext: ".sql", + start: "--", + line: "--", + end: "--", + singleLine: "--", + }, + php: { + ext: ".php", + start: "/*", + line: " *", + end: " */", + singleLine: "//", + }, + python: { + ext: ".py", + start: "#", + line: "#", + end: "#", + singleLine: "#", + }, + python3: { + ext: ".py", + start: "#", + line: "#", + end: "#", + singleLine: "#", + }, + ruby: { + ext: ".rb", + start: "#", + line: "#", + end: "#", + singleLine: "#", + }, + rust: { + ext: ".rs", + start: "/*", + line: " *", + end: " */", + singleLine: "//", + }, + scala: { + ext: ".scala", + start: "/*", + line: " *", + end: " */", + singleLine: "//", + }, + swift: { + ext: ".swift", + start: "/*", + line: " *", + end: " */", + singleLine: "//", + }, + typescript: { + ext: ".ts", + start: "/*", + line: " *", + end: " */", + singleLine: "//", + }, + }; + + getFileExtByLanguage(lang) { + const res = this.storageFileInfo[lang]; + return res ? res.ext : ".raw"; + } + + getCommentStyleByLanguage(lang) { + const res = this.storageFileInfo[lang]; + return res; + } + + public init() { + this.mkdir(this.homeDir()); + this.initCache(); + } + + public isWindows() { + return process.platform === "win32"; + } + + public userHomeDir() { + return process.env.HOME || process.env.USERPROFILE; + } + + public homeDir() { + return path.join(this.userHomeDir(), ".lcpr"); + } + + public appDir() { + const config = require("./configUtils"); + return path.join(this.homeDir(), config.app || "leetcode"); + } + + // 缓存目录 + public cacheDir() { + return path.join(this.appDir(), "cache"); + } + + // 代码目录 + public codeDir(dir) { + return path.join(__dirname, dir || ""); + } + + // 缓存目录文件 + public cacheFile(k) { + return path.join(this.cacheDir(), k + ".json"); + } + + // public configFile() { + // return path.join(this.homeDir(), 'config.json'); + // }; + + // 插件代码目录 + public listCodeDir(dir) { + dir = this.codeDir(dir); + let that = this; + return this.list(dir).map(function (f) { + const fullpath = path.join(dir, f); + const ext = path.extname(f); + const name = path.basename(f, ext); + + let data = null; + switch (ext) { + case ".js": + data = require(fullpath).pluginObj; + break; + case ".json": + data = JSON.parse(that.getData(fullpath)); + break; + } + return { name: name, data: data, file: f }; + }); + } + + public initCache() { + this.mkdir(this.cacheDir()); + } + public deleteAllCache() { + this.listCache().forEach((value) => { + this.delCache(value.name); + }); + } + + public getCache(k) { + const fullpath = this.cacheFile(k); + if (!this.exist(fullpath)) return null; + + return JSON.parse(this.getData(fullpath)); + } + + public setCache(k, v) { + const fullpath = this.cacheFile(k); + this.write(fullpath, JSON.stringify(v)); + return true; + } + + public delCache(k) { + const fullpath = this.cacheFile(k); + if (!this.exist(fullpath)) return false; + + this.rm(fullpath); + return true; + } + + public listCache(): Array { + let that = this; + return this.list(this.cacheDir()) + .filter((x) => path.extname(x) === ".json") + .map(function (filename) { + const k = path.basename(filename, ".json"); + const stat = that.stat(that.cacheFile(k)); + return { + name: k, + size: stat.size, + mtime: stat.mtime, + }; + }); + } + + public mkdir(fullpath) { + if (fs.existsSync(fullpath)) return; + mkdirp.sync(fullpath); + } + + public exist(fullpath) { + return fs.existsSync(fullpath); + } + + public rm(fullpath) { + return fs.unlinkSync(fullpath); + } + + public mv(src, dst) { + return fs.renameSync(src, dst); + } + + public list(dir) { + return fs.readdirSync(dir); + } + + public stat(fullpath) { + return fs.statSync(fullpath); + } + + public write(fullpath, data) { + return fs.writeFileSync(fullpath, data); + } + + public name(fullpath) { + return path.basename(fullpath, path.extname(fullpath)); + } + + public getData(fullpath) { + return fs.existsSync(fullpath) ? fs.readFileSync(fullpath).toString() : null; + } + + // 获取要提交测试的数据 + public codeData(fullpath) { + const data = this.getData(fullpath); + + if (data === null) { + return null; + } + + const lines = data.split(/\r\n|\n|\r/); + const start = lines.findIndex((x) => x.indexOf("@lc code=start") !== -1); + const end = lines.findIndex((x) => x.indexOf("@lc code=end") !== -1); + + if (start !== -1 && end !== -1 && start + 1 <= end) { + return lines.slice(start + 1, end).join(os.EOL); + } + + return data; + } + + /** + * name + */ + public getAllCase(a_desc) { + let new_desc = a_desc.replace(/<\/sup>/gm, "").replace(//gm, "^"); + new_desc = require("he").decode(require("cheerio").load(new_desc).root().text()); + // NOTE: wordwrap internally uses '\n' as EOL, so here we have to + // remove all '\r' in the raw string. + new_desc = new_desc.replace(/\r\n/g, "\n").replace(/^ /gm, ""); + let input = require("wordwrap")(120)(new_desc).split("\n"); + let temp_test: Array = []; + let start_flag = false; + let temp_collect = ""; + for (let all_input = 0; all_input < input.length; all_input++) { + const element = input[all_input]; + let check_index = element.indexOf("输入:"); + + if (check_index == -1) { + check_index = element.indexOf("输入:"); + } + + if (check_index == -1) { + check_index = element.indexOf("Input:"); + } + if (check_index != -1) { + temp_collect += element.substring(check_index + 1); + start_flag = true; + continue; + } + check_index = element.indexOf("输出:"); + if (check_index == -1) { + check_index = element.indexOf("输出:"); + } + if (check_index == -1) { + check_index = element.indexOf("Output:"); + } + if (check_index != -1) { + start_flag = false; + } + if (start_flag) { + temp_collect += element; + } else { + if (temp_collect.length > 0) { + let new_ele = temp_collect; + let temp_case: Array = []; + let wait_cur = ""; + let no_need_flag = false; + for (let index = new_ele.length - 1; index >= 0; index--) { + if (no_need_flag) { + if (new_ele[index] == ",") { + no_need_flag = false; + } + } else { + if (new_ele[index] == "=") { + temp_case.push(wait_cur.trim()); + no_need_flag = true; + wait_cur = ""; + } else { + wait_cur = new_ele[index] + wait_cur; + } + } + } + let new_temp_case: Array = []; + for (let tci = temp_case.length - 1; tci >= 0; tci--) { + new_temp_case.push(temp_case[tci]); + } + temp_test.push(new_temp_case); + temp_collect = ""; + } + } + } + + return temp_test; + } + + // 加载输出模板数据 + public render(tpl, data) { + const tplfile = path.join(__dirname, "..", "..", "..", "..", "resources", "templates", tpl + ".tpl"); + let result = _.template(this.getData(tplfile).replace(/\r\n/g, "\n"))(data); + if (this.isWindows()) { + result = result.replace(/\n/g, "\r\n"); + } else { + result = result.replace(/\r\n/g, "\n"); + } + return result; + } + + public fmt(format, data) { + return _.template(format)(data); + } + + // 去掉头尾的\n + public deleteWriteCaseHeadENDn(testCase) { + if (testCase.length < 3) { + return testCase; + } + let start = 0; + let end = testCase.length - 1; + let flag = false; + while (start < end - 1 && testCase[start] == "\n") { + start++; + flag = true; + } + while (end >= 1 && testCase[end] == "\n") { + end--; + flag = true; + } + if (flag) { + return testCase.substring(start, end + 1); + } + return testCase; + } + + public meta(filename) { + const m = Object.assign({}, defaultMETA, {}); + + let file_info = this.getData(filename).split("\n"); + + let temp_test: Array = []; + let caseFlag: boolean = false; + let curCase = ""; + + for (let all_input = 0; all_input < file_info.length; all_input++) { + const lineContent = file_info[all_input]; + if (caseFlag && lineContent.indexOf("@lcpr case=end") < 0) { + curCase += lineContent + .replace(/#/g, "") + .replace(/\/\//g, "") + .replace(/--/g, "") + .replace(/\s+/g, "") + .replace(/\\n/g, "\n"); + } + // 收集所有用例 + if (lineContent.indexOf("@lcpr case=start") >= 0) { + caseFlag = true; + } + if (caseFlag && lineContent.indexOf("@lcpr case=end") >= 0) { + temp_test.push(this.deleteWriteCaseHeadENDn(curCase)); + curCase = ""; + caseFlag = false; + } + if (lineContent.indexOf(" @lc app=") >= 0) { + // @lc app=leetcode.cn id=剑指 Offer II 116 lang=cpp + let id_right = lineContent.split("id=")[1]; + let lang_cat = id_right.split("lang="); + let id = lang_cat[0].trim(); + let lang = lang_cat[1].trim(); + m.id = id; + m.fid = id; + m.lang = lang; + } + m.writeCase = temp_test; + } + return m; + } +} + +export const storageUtils: StorageUtils = new StorageUtils(); diff --git a/src/service/BaseWebviewService.ts b/src/service/BaseWebviewService.ts index 3646604..7345d28 100644 --- a/src/service/BaseWebviewService.ts +++ b/src/service/BaseWebviewService.ts @@ -7,7 +7,6 @@ * Copyright (c) 2022 ccagml . All rights reserved. */ - import { commands, ConfigurationChangeEvent, Disposable, ViewColumn, WebviewPanel, window, workspace } from "vscode"; import { markdownService } from "./MarkdownService"; import { IWebViewOption } from "../model/Model"; @@ -15,72 +14,77 @@ import { openSettingsEditor } from "../utils/ConfigUtils"; import { promptHintMessage } from "../utils/OutputUtils"; export abstract class BaseWebViewService implements Disposable { + protected readonly viewType: string = "leetcode.webview"; + protected panel: WebviewPanel | undefined; + private listeners: Disposable[] = []; - protected readonly viewType: string = "leetcode.webview"; - protected panel: WebviewPanel | undefined; - private listeners: Disposable[] = []; - - public dispose(): void { - if (this.panel) { - this.panel.dispose(); - } + public dispose(): void { + if (this.panel) { + this.panel.dispose(); } + } - protected showWebviewInternal(): void { - const { title, viewColumn, preserveFocus } = this.getWebviewOption(); - if (!this.panel) { - this.panel = window.createWebviewPanel(this.viewType, title, { viewColumn, preserveFocus }, { - enableScripts: true, - enableCommandUris: true, - enableFindWidget: true, - retainContextWhenHidden: true, - localResourceRoots: markdownService.localResourceRoots, - }); - this.panel.onDidDispose(this.onDidDisposeWebview, this, this.listeners); - this.panel.webview.onDidReceiveMessage(this.onDidReceiveMessage, this, this.listeners); - workspace.onDidChangeConfiguration(this.onDidChangeConfiguration, this, this.listeners); - } else { - this.panel.title = title; - if (viewColumn === ViewColumn.Two) { - // Make sure second group exists. See vscode#71608 issue - commands.executeCommand("workbench.action.focusSecondEditorGroup").then(() => { - this.panel!.reveal(viewColumn, preserveFocus); - }); - } else { - this.panel.reveal(viewColumn, preserveFocus); - } + protected showWebviewInternal(): void { + const { title, viewColumn, preserveFocus } = this.getWebviewOption(); + if (!this.panel) { + this.panel = window.createWebviewPanel( + this.viewType, + title, + { viewColumn, preserveFocus }, + { + enableScripts: true, + enableCommandUris: true, + enableFindWidget: true, + retainContextWhenHidden: true, + localResourceRoots: markdownService.localResourceRoots, } - this.panel.webview.html = this.getWebviewContent(); - this.showMarkdownConfigHint(); + ); + this.panel.onDidDispose(this.onDidDisposeWebview, this, this.listeners); + this.panel.webview.onDidReceiveMessage(this.onDidReceiveMessage, this, this.listeners); + workspace.onDidChangeConfiguration(this.onDidChangeConfiguration, this, this.listeners); + } else { + this.panel.title = title; + if (viewColumn === ViewColumn.Two) { + // Make sure second group exists. See vscode#71608 issue + commands.executeCommand("workbench.action.focusSecondEditorGroup").then(() => { + this.panel!.reveal(viewColumn, preserveFocus); + }); + } else { + this.panel.reveal(viewColumn, preserveFocus); + } } + this.panel.webview.html = this.getWebviewContent(); + this.showMarkdownConfigHint(); + } - protected onDidDisposeWebview(): void { - this.panel = undefined; - for (const listener of this.listeners) { - listener.dispose(); - } - this.listeners = []; + protected onDidDisposeWebview(): void { + this.panel = undefined; + for (const listener of this.listeners) { + listener.dispose(); } + this.listeners = []; + } - protected async onDidChangeConfiguration(event: ConfigurationChangeEvent): Promise { - if (this.panel && event.affectsConfiguration("markdown")) { - this.panel.webview.html = this.getWebviewContent(); - } + protected async onDidChangeConfiguration(event: ConfigurationChangeEvent): Promise { + if (this.panel && event.affectsConfiguration("markdown")) { + this.panel.webview.html = this.getWebviewContent(); } + } - protected async onDidReceiveMessage(_message: any): Promise { /* no special rule */ } + protected async onDidReceiveMessage(_message: any): Promise { + /* no special rule */ + } - protected abstract getWebviewOption(): IWebViewOption; + protected abstract getWebviewOption(): IWebViewOption; - protected abstract getWebviewContent(): string; + protected abstract getWebviewContent(): string; - private async showMarkdownConfigHint(): Promise { - await promptHintMessage( - "hint.configWebviewMarkdown", - 'You can change the webview appearance ("fontSize", "lineWidth" & "fontFamily") in "markdown.preview" configuration.', - "Open settings", - (): Promise => openSettingsEditor("markdown.preview"), - ); - } + private async showMarkdownConfigHint(): Promise { + await promptHintMessage( + "hint.configWebviewMarkdown", + 'You can change the webview appearance ("fontSize", "lineWidth" & "fontFamily") in "markdown.preview" configuration.', + "Open settings", + (): Promise => openSettingsEditor("markdown.preview") + ); + } } - diff --git a/src/service/EventService.ts b/src/service/EventService.ts index a89d488..03f096e 100644 --- a/src/service/EventService.ts +++ b/src/service/EventService.ts @@ -7,43 +7,38 @@ * Copyright (c) 2022 ccagml . All rights reserved. */ - - import { EventEmitter } from "events"; - import { UserStatus } from "../model/Model"; import { ISubmitEvent } from "../model/Model"; import { statusBarService } from "../service/StatusBarService"; import { treeDataService } from "../service/TreeDataService"; class EventService extends EventEmitter { - - constructor() { - super(); - } - - /** - * 监听事件 - */ - public add_event() { - this.on("statusChanged", (userStatus: UserStatus, userName?: string) => { - statusBarService.update_status(userStatus, userName); - statusBarService.update(); - treeDataService.cleanUserScore(); - treeDataService.refresh(); - }); - this.on("submit", (e: ISubmitEvent) => { - treeDataService.checkSubmit(e); - }); - - this.on("searchUserContest", (tt) => { - statusBarService.update_UserContestInfo(tt); - statusBarService.update(); - treeDataService.refresh(); - }); - } + constructor() { + super(); + } + + /** + * 监听事件 + */ + public add_event() { + this.on("statusChanged", (userStatus: UserStatus, userName?: string) => { + statusBarService.update_status(userStatus, userName); + statusBarService.update(); + treeDataService.cleanUserScore(); + treeDataService.refresh(); + }); + this.on("submit", (e: ISubmitEvent) => { + treeDataService.checkSubmit(e); + }); + + this.on("searchUserContest", (tt) => { + statusBarService.update_UserContestInfo(tt); + statusBarService.update(); + treeDataService.refresh(); + }); + } } export const eventService: EventService = new EventService(); - diff --git a/src/service/ExecuteService.ts b/src/service/ExecuteService.ts index d33ef5e..5becaba 100644 --- a/src/service/ExecuteService.ts +++ b/src/service/ExecuteService.ts @@ -7,7 +7,6 @@ * Copyright (c) 2022 ccagml . All rights reserved. */ - import * as cp from "child_process"; import * as fse from "fs-extra"; import * as os from "os"; @@ -22,253 +21,331 @@ import * as systemUtils from "../utils/SystemUtils"; import { toWslPath, useWsl } from "../utils/SystemUtils"; class ExecuteService implements Disposable { - private leetCodeCliResourcesRootPath: string; - private leetCodeCliRootPath: string; - private nodeExecutable: string; - private configurationChangeListener: Disposable; - - constructor() { - // this.leetCodeCliResourcesRootPath = path.join(__dirname, "..", "..", "node_modules", "childProcessCall"); - if (!systemUtils.useVscodeNode()) { - this.leetCodeCliResourcesRootPath = path.join(__dirname, "..", "..", "..", "resources"); - } - this.leetCodeCliRootPath = path.join(__dirname, "..", "..", "..", "out", "src", "childProcessCall"); + private leetCodeCliResourcesRootPath: string; + private leetCodeCliRootPath: string; + private nodeExecutable: string; + private configurationChangeListener: Disposable; + + constructor() { + // this.leetCodeCliResourcesRootPath = path.join(__dirname, "..", "..", "node_modules", "rpc"); + if (!systemUtils.useVscodeNode()) { + this.leetCodeCliResourcesRootPath = path.join(__dirname, "..", "..", "..", "resources"); + } + this.leetCodeCliRootPath = path.join(__dirname, "..", "..", "..", "out", "src", "rpc"); + this.nodeExecutable = this.initNodePath(); + this.configurationChangeListener = workspace.onDidChangeConfiguration((event: ConfigurationChangeEvent) => { + if (event.affectsConfiguration("leetcode-problem-rating.nodePath")) { this.nodeExecutable = this.initNodePath(); - this.configurationChangeListener = workspace.onDidChangeConfiguration((event: ConfigurationChangeEvent) => { - if (event.affectsConfiguration("leetcode-problem-rating.nodePath")) { - this.nodeExecutable = this.initNodePath(); - } - }, this); + } + }, this); + } + + public async getLeetCodeBinaryPath(): Promise { + if (systemUtils.useVscodeNode()) { + return `${path.join(this.leetCodeCliRootPath, "childMain.js")}`; + } else { + if (systemUtils.useWsl()) { + return `${await systemUtils.toWslPath(`"${path.join(this.leetCodeCliResourcesRootPath, "bin", "leetcode")}"`)}`; + } + return `"${path.join(this.leetCodeCliResourcesRootPath, "bin", "leetcode")}"`; } + } - public async getLeetCodeBinaryPath(): Promise { - if (systemUtils.useVscodeNode()) { - return `${path.join(this.leetCodeCliRootPath, "cli.js")}`; - } else { - if (systemUtils.useWsl()) { - return `${await systemUtils.toWslPath(`"${path.join(this.leetCodeCliResourcesRootPath, "bin", "leetcode")}"`)}`; - } - return `"${path.join(this.leetCodeCliResourcesRootPath, "bin", "leetcode")}"`; - } + public async checkNodeEnv(context: ExtensionContext): Promise { + const hasInited: boolean | undefined = context.globalState.get(leetcodeHasInited); + if (!hasInited) { + await this.removeOldCache(); } - - public async checkNodeEnv(context: ExtensionContext): Promise { - const hasInited: boolean | undefined = context.globalState.get(leetcodeHasInited); - if (!hasInited) { - await this.removeOldCache(); - } - if (this.nodeExecutable !== "node") { - if (!await fse.pathExists(this.nodeExecutable)) { - throw new Error(`The Node.js executable does not exist on path ${this.nodeExecutable}`); - } - // Wrap the executable with "" to avoid space issue in the path. - this.nodeExecutable = `"${this.nodeExecutable}"`; - if (useWsl()) { - this.nodeExecutable = await toWslPath(this.nodeExecutable); - } - } - try { - await this.executeCommandEx(this.nodeExecutable, ["-v"]); - } catch (error) { - const choice: MessageItem | undefined = await window.showErrorMessage( - "LeetCode extension needs Node.js installed in environment path", - DialogOptions.open, - ); - if (choice === DialogOptions.open) { - openUrl("https://nodejs.org"); - } - return false; - } - context.globalState.update(leetcodeHasInited, true); - return true; + if (this.nodeExecutable !== "node") { + if (!(await fse.pathExists(this.nodeExecutable))) { + throw new Error(`The Node.js executable does not exist on path ${this.nodeExecutable}`); + } + // Wrap the executable with "" to avoid space issue in the path. + this.nodeExecutable = `"${this.nodeExecutable}"`; + if (useWsl()) { + this.nodeExecutable = await toWslPath(this.nodeExecutable); + } } - - public async deleteCache() { - try { - await this.executeCommandEx(this.nodeExecutable, [await this.getLeetCodeBinaryPath(), "cache", "-d"]); - } catch (error) { - await promptForOpenOutputChannel("Failed to delete cache. 请查看控制台信息~", DialogType.error); - } + try { + await this.executeCommandEx(this.nodeExecutable, ["-v"]); + } catch (error) { + const choice: MessageItem | undefined = await window.showErrorMessage( + "LeetCode extension needs Node.js installed in environment path", + DialogOptions.open + ); + if (choice === DialogOptions.open) { + openUrl("https://nodejs.org"); + } + return false; } - - public async getUserInfo(): Promise { - return await this.executeCommandEx(this.nodeExecutable, [await this.getLeetCodeBinaryPath(), "user"]); + context.globalState.update(leetcodeHasInited, true); + return true; + } + + public async deleteCache() { + try { + await this.executeCommandEx(this.nodeExecutable, [await this.getLeetCodeBinaryPath(), "cache", "-d"]); + } catch (error) { + await promptForOpenOutputChannel("Failed to delete cache. 请查看控制台信息~", DialogType.error); } + } - public async signOut(): Promise { - return await this.executeCommandEx(this.nodeExecutable, [await this.getLeetCodeBinaryPath(), "user", "-L"]); - } + public async getUserInfo(): Promise { + return await this.executeCommandEx(this.nodeExecutable, [await this.getLeetCodeBinaryPath(), "user"]); + } - public async listProblems(showLocked: boolean, needTranslation: boolean): Promise { - const cmd: string[] = [await this.getLeetCodeBinaryPath(), "list"]; - if (!needTranslation) { - cmd.push("-T"); // use -T to prevent translation - } - if (!showLocked) { - cmd.push("-q"); - cmd.push("L"); - } - return await this.executeCommandEx(this.nodeExecutable, cmd); - } + public async signOut(): Promise { + return await this.executeCommandEx(this.nodeExecutable, [await this.getLeetCodeBinaryPath(), "user", "-L"]); + } - public async showProblem(problemNode: IProblem, language: string, filePath: string, showDescriptionInComment: boolean = false, needTranslation: boolean): Promise { - const templateType: string = showDescriptionInComment ? "-cx" : "-c"; - const cmd: string[] = [await this.getLeetCodeBinaryPath(), "show", problemNode.qid, templateType, "-l", language]; - - if (!needTranslation) { - cmd.push("-T"); // use -T to force English version - } - - if (!await fse.pathExists(filePath)) { - await fse.createFile(filePath); - const codeTemplate: string = await this.executeCommandWithProgressEx("Fetching problem data...", this.nodeExecutable, cmd); - await fse.writeFile(filePath, codeTemplate); - } + public async listProblems(showLocked: boolean, needTranslation: boolean): Promise { + const cmd: string[] = [await this.getLeetCodeBinaryPath(), "list"]; + if (!needTranslation) { + cmd.push("-T"); // use -T to prevent translation } - - - public async showSolution(input: string, language: string, needTranslation: boolean): Promise { - // solution don't support translation - const cmd: string[] = [await this.getLeetCodeBinaryPath(), "show", input, "--solution", "-l", language]; - if (!needTranslation) { - cmd.push("-T"); - } - const solution: string = await this.executeCommandWithProgressEx("Fetching top voted solution from discussions...", this.nodeExecutable, cmd); - return solution; + if (!showLocked) { + cmd.push("-q"); + cmd.push("L"); } - - public async getUserContest(needTranslation: boolean, username: string): Promise { - // solution don't support translation - const cmd: string[] = [await this.getLeetCodeBinaryPath(), "query", "-b", username]; - if (!needTranslation) { - cmd.push("-T"); - } - const solution: string = await this.executeCommandWithProgressEx("Fetching UserContest...", this.nodeExecutable, cmd); - return solution; + return await this.executeCommandEx(this.nodeExecutable, cmd); + } + + public async showProblem( + problemNode: IProblem, + language: string, + filePath: string, + showDescriptionInComment: boolean = false, + needTranslation: boolean + ): Promise { + const templateType: string = showDescriptionInComment ? "-cx" : "-c"; + const cmd: string[] = [await this.getLeetCodeBinaryPath(), "show", problemNode.qid, templateType, "-l", language]; + + if (!needTranslation) { + cmd.push("-T"); // use -T to force English version } - public async getScoreDataOnline(): Promise { - // solution don't support translation - const cmd: string[] = [await this.getLeetCodeBinaryPath(), "query", "-c"]; - const solution: string = await this.executeCommandWithProgressEx("get data from https://zerotrac.github.io/leetcode_problem_rating/data.json", this.nodeExecutable, cmd); - return solution; + if (!(await fse.pathExists(filePath))) { + await fse.createFile(filePath); + const codeTemplate: string = await this.executeCommandWithProgressEx( + "Fetching problem data...", + this.nodeExecutable, + cmd + ); + await fse.writeFile(filePath, codeTemplate); } + } - public async getTestApi(username: string): Promise { - // solution don't support translation - const cmd: string[] = [await this.getLeetCodeBinaryPath(), "query", "-z", username]; - const solution: string = await this.executeCommandWithProgressEx("Fetching testapi...", this.nodeExecutable, cmd); - return solution; + public async showSolution(input: string, language: string, needTranslation: boolean): Promise { + // solution don't support translation + const cmd: string[] = [await this.getLeetCodeBinaryPath(), "show", input, "--solution", "-l", language]; + if (!needTranslation) { + cmd.push("-T"); } - - public async getTodayQuestion(needTranslation: boolean): Promise { - // solution don't support translation - const cmd: string[] = [await this.getLeetCodeBinaryPath(), "query", "-a"]; - if (!needTranslation) { - cmd.push("-T"); - } - const solution: string = await this.executeCommandWithProgressEx("Fetching today question...", this.nodeExecutable, cmd); - return solution; + const solution: string = await this.executeCommandWithProgressEx( + "Fetching top voted solution from discussions...", + this.nodeExecutable, + cmd + ); + return solution; + } + + public async getUserContest(needTranslation: boolean, username: string): Promise { + // solution don't support translation + const cmd: string[] = [await this.getLeetCodeBinaryPath(), "query", "-b", username]; + if (!needTranslation) { + cmd.push("-T"); } - - - public async getDescription(problemNodeId: string, needTranslation: boolean): Promise { - const cmd: string[] = [await this.getLeetCodeBinaryPath(), "show", problemNodeId, "-x"]; - if (!needTranslation) { - cmd.push("-T"); - } - return await this.executeCommandWithProgressEx("Fetching problem description...", this.nodeExecutable, cmd); + const solution: string = await this.executeCommandWithProgressEx( + "Fetching UserContest...", + this.nodeExecutable, + cmd + ); + return solution; + } + + public async getScoreDataOnline(): Promise { + // solution don't support translation + const cmd: string[] = [await this.getLeetCodeBinaryPath(), "query", "-c"]; + const solution: string = await this.executeCommandWithProgressEx( + "get data from https://zerotrac.github.io/leetcode_problem_rating/data.json", + this.nodeExecutable, + cmd + ); + return solution; + } + + public async getTestApi(username: string): Promise { + // solution don't support translation + const cmd: string[] = [await this.getLeetCodeBinaryPath(), "query", "-z", username]; + const solution: string = await this.executeCommandWithProgressEx("Fetching testapi...", this.nodeExecutable, cmd); + return solution; + } + + public async getTodayQuestion(needTranslation: boolean): Promise { + // solution don't support translation + const cmd: string[] = [await this.getLeetCodeBinaryPath(), "query", "-a"]; + if (!needTranslation) { + cmd.push("-T"); } - - - public async submitSolution(filePath: string): Promise { - try { - if (systemUtils.useVscodeNode()) { - return await this.executeCommandWithProgressEx("Submitting to LeetCode...", this.nodeExecutable, [await this.getLeetCodeBinaryPath(), "submit", `${filePath}`]); - } - return await this.executeCommandWithProgressEx("Submitting to LeetCode...", this.nodeExecutable, [await this.getLeetCodeBinaryPath(), "submit", `"${filePath}"`]); - } catch (error) { - if (error.result) { - return error.result; - } - throw error; - } + const solution: string = await this.executeCommandWithProgressEx( + "Fetching today question...", + this.nodeExecutable, + cmd + ); + return solution; + } + + public async getDescription(problemNodeId: string, needTranslation: boolean): Promise { + const cmd: string[] = [await this.getLeetCodeBinaryPath(), "show", problemNodeId, "-x"]; + if (!needTranslation) { + cmd.push("-T"); } - - public async testSolution(filePath: string, testString?: string, allCase?: boolean): Promise { - if (testString) { - if (systemUtils.useVscodeNode()) { - return await this.executeCommandWithProgressEx("Submitting to LeetCode...", this.nodeExecutable, [await this.getLeetCodeBinaryPath(), "test", `${filePath}`, "-t", `${testString}`]); - } - return await this.executeCommandWithProgressEx("Submitting to LeetCode...", this.nodeExecutable, [await this.getLeetCodeBinaryPath(), "test", `"${filePath}"`, "-t", `${testString}`]); - } - if (allCase) { - if (systemUtils.useVscodeNode()) { - return await this.executeCommandWithProgressEx("Submitting to LeetCode...", this.nodeExecutable, [await this.getLeetCodeBinaryPath(), "test", `${filePath}`, "-a"]); - } - return await this.executeCommandWithProgressEx("Submitting to LeetCode...", this.nodeExecutable, [await this.getLeetCodeBinaryPath(), "test", `"${filePath}"`, "-a"]); - } - if (systemUtils.useVscodeNode()) { - return await this.executeCommandWithProgressEx("Submitting to LeetCode...", this.nodeExecutable, [await this.getLeetCodeBinaryPath(), "test", `${filePath}`]); - } - return await this.executeCommandWithProgressEx("Submitting to LeetCode...", this.nodeExecutable, [await this.getLeetCodeBinaryPath(), "test", `"${filePath}"`]); + return await this.executeCommandWithProgressEx("Fetching problem description...", this.nodeExecutable, cmd); + } + + public async submitSolution(filePath: string): Promise { + try { + if (systemUtils.useVscodeNode()) { + return await this.executeCommandWithProgressEx("Submitting to LeetCode...", this.nodeExecutable, [ + await this.getLeetCodeBinaryPath(), + "submit", + `${filePath}`, + ]); + } + return await this.executeCommandWithProgressEx("Submitting to LeetCode...", this.nodeExecutable, [ + await this.getLeetCodeBinaryPath(), + "submit", + `"${filePath}"`, + ]); + } catch (error) { + if (error.result) { + return error.result; + } + throw error; } - - public async switchEndpoint(endpoint: string): Promise { - switch (endpoint) { - case Endpoint.LeetCodeCN: - return await this.executeCommandEx(this.nodeExecutable, [await this.getLeetCodeBinaryPath(), "plugin", "-e", "leetcode.cn"]); - case Endpoint.LeetCode: - default: - return await this.executeCommandEx(this.nodeExecutable, [await this.getLeetCodeBinaryPath(), "plugin", "-d", "leetcode.cn"]); - } + } + + public async testSolution(filePath: string, testString?: string, allCase?: boolean): Promise { + if (testString) { + if (systemUtils.useVscodeNode()) { + return await this.executeCommandWithProgressEx("Submitting to LeetCode...", this.nodeExecutable, [ + await this.getLeetCodeBinaryPath(), + "test", + `${filePath}`, + "-t", + `${testString}`, + ]); + } + return await this.executeCommandWithProgressEx("Submitting to LeetCode...", this.nodeExecutable, [ + await this.getLeetCodeBinaryPath(), + "test", + `"${filePath}"`, + "-t", + `${testString}`, + ]); } - - public async toggleFavorite(node: IProblem, addToFavorite: boolean): Promise { - const commandParams: string[] = [await this.getLeetCodeBinaryPath(), "star", node.id]; - if (!addToFavorite) { - commandParams.push("-d"); - } - await this.executeCommandWithProgressEx("Updating the favorite list...", "node", commandParams); + if (allCase) { + if (systemUtils.useVscodeNode()) { + return await this.executeCommandWithProgressEx("Submitting to LeetCode...", this.nodeExecutable, [ + await this.getLeetCodeBinaryPath(), + "test", + `${filePath}`, + "-a", + ]); + } + return await this.executeCommandWithProgressEx("Submitting to LeetCode...", this.nodeExecutable, [ + await this.getLeetCodeBinaryPath(), + "test", + `"${filePath}"`, + "-a", + ]); } - - - public get node(): string { - return this.nodeExecutable; + if (systemUtils.useVscodeNode()) { + return await this.executeCommandWithProgressEx("Submitting to LeetCode...", this.nodeExecutable, [ + await this.getLeetCodeBinaryPath(), + "test", + `${filePath}`, + ]); } - - public dispose(): void { - this.configurationChangeListener.dispose(); + return await this.executeCommandWithProgressEx("Submitting to LeetCode...", this.nodeExecutable, [ + await this.getLeetCodeBinaryPath(), + "test", + `"${filePath}"`, + ]); + } + + public async switchEndpoint(endpoint: string): Promise { + switch (endpoint) { + case Endpoint.LeetCodeCN: + return await this.executeCommandEx(this.nodeExecutable, [ + await this.getLeetCodeBinaryPath(), + "plugin", + "-e", + "leetcode.cn", + ]); + case Endpoint.LeetCode: + default: + return await this.executeCommandEx(this.nodeExecutable, [ + await this.getLeetCodeBinaryPath(), + "plugin", + "-d", + "leetcode.cn", + ]); } + } - private initNodePath(): string { - if (systemUtils.useVscodeNode()) { - return "node"; - } - return getNodePath(); + public async toggleFavorite(node: IProblem, addToFavorite: boolean): Promise { + const commandParams: string[] = [await this.getLeetCodeBinaryPath(), "star", node.id]; + if (!addToFavorite) { + commandParams.push("-d"); } + await this.executeCommandWithProgressEx("Updating the favorite list...", "node", commandParams); + } - private async executeCommandEx(command: string, args: string[], options: cp.SpawnOptions = { shell: true }): Promise { - if (systemUtils.useWsl()) { - return await executeCommand("wsl", [command].concat(args), options); - } - return await executeCommand(command, args, options); - } + public get node(): string { + return this.nodeExecutable; + } - private async executeCommandWithProgressEx(message: string, command: string, args: string[], options: cp.SpawnOptions = { shell: true }): Promise