Skip to main content

15. 3Sum

· 2 min read
Shi Xinyu
Front End Developer

Given an integer array nums, return all the triplets [nums[i], nums[j], nums[k]] such that i != j, i != k, and j != k, and nums[i] + nums[j] + nums[k] == 0.

Notice that the solution set must not contain duplicate triplets.

Example

Example 1:

Input: nums = [-1,0,1,2,-1,-4] Output: [[-1,-1,2],[-1,0,1]] Explanation: nums[0] + nums[1] + nums[2] = (-1) + 0 + 1 = 0. nums[1] + nums[2] + nums[4] = 0 + 1 + (-1) = 0. nums[0] + nums[3] + nums[4] = (-1) + 2 + (-1) = 0. The distinct triplets are [-1,0,1] and [-1,-1,2]. Notice that the order of the output and the order of the triplets does not matter.

Example 2:

Input: nums = [0,1,1] Output: [] Explanation: The only possible triplet does not sum up to 0.

Example 3:

Input: nums = [0,0,0] Output: [[0,0,0]] Explanation: The only possible triplet sums up to 0.

/**
* @param {number[][]} matrix
* @return {number[][]}
*/
function threeSum(input: number[]) {
const length = input.length;
input.sort((a, b) => a - b);
const res = new Set<string>();

function checkPosition(mid: number) {
let left = mid - 1;
let right = mid + 1;

while (left >= 0 && right < length) {
const sum = input[left] + input[mid] + input[right];
if (sum === 0) {
res.add([input[left], input[mid], input[right]].join(","));
left--;
}
if (sum < 0) {
right++;
}
if (sum > 0) {
left--;
}
}
}

for (let i = 1; i < length - 1; i++) {
checkPosition(i);
}
return [...res].map((v) => v.split(","));
}

16

· One min read
Shi Xinyu
Front End Developer

Given a 2D integer array matrix, return the transpose of matrix.

The transpose of a matrix is the matrix flipped over its main diagonal, switching the matrix's row and column indices. link: https://leetcode.com/problems/transpose-matrix/

Example

Example 1:

Input: matrix = [[1,2,3],[4,5,6],[7,8,9]] Output: [[1,4,7],[2,5,8],[3,6,9]]

Example 2:

Input: matrix = [[1,2,3],[4,5,6]] Output: [[1,4],[2,5],[3,6]]

/**
* @param {number[][]} matrix
* @return {number[][]}
*/
var transpose = function (matrix) {
if (!matrix.length) return;
const numOfCols = matrix[0].length;
const numOfRows = matrix.length;
const result = [];
for (let i = 0; i < numOfCols; i++) {
result.push([]);
}
for (let i = 0; i < numOfCols; i++) {
for (let j = 0; j < numOfRows; j++) {
result[i][j] = matrix[j][i];
}
}
return result;
};

Interestingly enough, [3, 0, -2, -1, 1, 2].sort() gives [ -1, -2, 0, 1, 2, 3 ]

lockfile debugging

· One min read
Shi Xinyu
Front End Developer

Ideally, we don't need a lockfile, like a npm-lock, a yarn-lock, or a pnpm-lock.yaml. A lockfile should be pure function of package.json.

But some idiots invented this ^ sign. Then all the troubles begins.

{
'pkg': "^2.2.0"
}

Could resolve to 2.2.0, 2.2.1 or sth else.

Then we need a lockfile, which could grow

A temp solution:

# clear node_modules in current folder
find . -name 'node_modules' -type d -prune -print -exec rm -rf '{}' \;
# clear the store
rm -rf node_modules && rm -rf ~/.pnpm-store

volta

· One min read
Shi Xinyu
Front End Developer

I am currently using nvm, node version manager. And as I am maintaining many projects, I found I am busy switching node and pnpm versions like blow:

node -v
nvm use node 18.19.0

corepack enable
corepack prepare pnpm@8.11.0 --activate

Considering I need to do it multiple times a day, an automation tool becomes a necessity. So I searched and the only answer seems to be Volta.

I like the volta pin function, it pins a volta setting in the package.json file.

{
"volta": {
"node": "16.19.1",
"pnpm": "8.11.0 "
}
}

Next time you enter the folder, volta will change your node version and pnpm version automatically.

The only concern about volta, is that it seems to be built for npm / yarn. Who's not using pnpm these days? But Volta only has limited support for pnpm. https://github.com/volta-cli/volta/issues/737

pnpm

· 3 min read
Shi Xinyu
Front End Developer

pnpm is a package manager for Node.js packages, or any other packages that are compatible with the npm ecosystem. It is optimized for fast installations and uses a shared cache for all packages.

why we use only pnpm is that it 1. saves disk space. 2. it solved the problem of phantom dependencies.

you will get a pnpm-lock.yaml file in your project. Ideally you don't need to commit it. For this file are to be a pure function of package.json. But in reality, we need to commit it. Some packages in package.json are labeled with a version range.

{
"dependencies": {
"react": "^16.13.1",
"react-dom": "^16.13.1"
}
}

here ^ means that the version range is any version that is compatible.

When you run pnpm install, pnpm will install the latest version of react and react-dom. If you run pnpm install again, pnpm will install the latest version of react and react-dom again. This is because the version range is not fixed. If you commit the pnpm-lock.yaml file, pnpm will install the same version of react and react-dom every time you run pnpm install.

under the hood

pnpm, much like maven, use hard link (and soft link).

Most single files are stored in the ~/.pnpm-store folder, based on hash of each file. Then when install, they are hard linked to the target project store.

Inside the node_modules folder, dependencies are soft linked.

tip

Consider this situation, when you delete the node_module folder to bin, and clean the bin, what is lost? Nothing is lost. inodes has referance count, files are not to be removed before reference is zero.

For typical linux systems, the process of creating hard link creates no new inode.

Creating a soft link creates a new special file.

(see Link)

tip

Some useful commands

pnpm why

pnpm prune

pnpm rebuild node-sass #who is still using node-sass in 2024?

if you read chinese, this is a good article to read: pnpm 是凭什么对 npm 和 yarn 降维打击的

首先介绍下 link,也就是软硬连接,这是操作系统提供的机制,硬连接就是同一个文件的不同引用,而软链接是新建一个文件,文件内容指向另一个路径。当然,这俩链接使用起来是差不多的。

所有的依赖都在这里铺平了,都是从全局 store 硬连接过来的,然后包和包之间的依赖关系是通过软链接组织的。

也就是说,所有的依赖都是从全局 store 硬连接到了 node_modules/.pnpm 下,然后之间通过软链接来相互依赖。

Encrypted Client Hello

· One min read
Shi Xinyu
Front End Developer

in 2020, Cloudflare introduced Encrypted Client Hello (ECH) to the world. It is a TLS extension that encrypts the Client Hello message. This is a great improvement to the TLS protocol, as it hides the SNI and other information from the network. This is a great improvement to the privacy of the users.

So with ech enabled, the network will only see the IP address of the server and the IP address of the client. This is a great improvement to the privacy of the users. Your ISP will not be able to see which domain you are browsing.

Example

so when using https://www.cloudflare.com/ you can use the following command to see if ECH is enabled:

curl -svo /dev/null https://www.cloudflare.com/ 2>&1 | grep -i ech

1390. Four Divisors

· One min read
Shi Xinyu
Front End Developer

Given an integer array nums, return the sum of divisors of the integers in that array that have exactly four divisors. If there is no such integer in the array, return 0.

Example

Example 1:

Input: nums = [21,4,7] Output: 32

Explanation: 21 has 4 divisors: 1, 3, 7, 21 4 has 3 divisors: 1, 2, 4 7 has 2 divisors: 1, 7 The answer is the sum of divisors of 21 only.

Example 2:

Input: nums = [21,21] Output: 64

Example 3:

Input: nums = [1,2,3,4,5] Output: 0

Constraints:

1 <= nums.length <= 104 1 <= nums[i] <= 105

/**
* @param {number[]} nums
* @return {number}
*/

const findDivisors = (num) => {
const divisors = [1, num];
const upperLimit = Math.sqrt(num);
if (Number.isInteger(upperLimit)) {
return [];
// divisors.push(upperLimit)
}
for (let i = 2; i < upperLimit; i++) {
if (Number.isInteger(num / i)) {
divisors.push(i);
divisors.push(num / i);
}
if (divisors.length > 4) {
return [];
}
}
if (divisors.length === 4) {
return divisors;
} else {
return [];
}
};
var sumFourDivisors = function (nums) {
const res = [];
const length = nums.length;
for (let i = 0; i < length; i++) {
res.push(findDivisors(nums[i]).reduce((prev, cur) => prev + cur, 0));
}
return res.reduce((prev, cur) => prev + cur, 0);
};

967. Numbers With Same Consecutive Differences

· One min read
Shi Xinyu
Front End Developer

Given two integers n and k, return an array of all the integers of length n where the difference between every two consecutive digits is k. You may return the answer in any order.

Note that the integers should not have leading zeros. Integers as 02 and 043 are not allowed.

Example

Example 1:

Input: n = 3, k = 7 Output: [181,292,707,818,929] Explanation: Note that 070 is not a valid number, because it has leading zeroes. Example 2:

Input: n = 2, k = 1 Output: [10,12,21,23,32,34,43,45,54,56,65,67,76,78,87,89,98]

Constraints:

2 <= n <= 9 0 <= k <= 9

/**
* @param {number} n
* @param {number} k
* @return {number[]}
*/
var numsSameConsecDiff = function (n, k) {
let results = new Set();
function travel(arr) {
if (arr.length === n) {
results.add(Number(arr.join("")));
} else if (arr.length < n) {
const last = arr[arr.length - 1];
const plus = last + k;
const minus = last - k;
if (plus >= 0 && plus <= 9) {
travel([...arr, plus]);
}
if (minus >= 0 && minus <= 9) {
travel([...arr, minus]);
}
}
}
for (let i = 1; i < 10; i++) {
travel([i]);
}
return [...results];
};

1464. Maximum Product of Two Elements in an Array

· One min read
Shi Xinyu
Front End Developer

Given a 2D integer array matrix, return the transpose of matrix.

Given the array of integers nums, you will choose two different indices i and j of that array. Return the maximum value of (nums[i]-1)*(nums[j]-1).

Example

Example 1:

Input: nums = [3,4,5,2] Output: 12 Explanation: If you choose the indices i=1 and j=2 (indexed from 0), you will get the maximum value, that is, (nums[1]-1)(nums[2]-1) = (4-1)(5-1) = 3*4 = 12. Example 2:

Input: nums = [1,5,4,5] Output: 16 Explanation: Choosing the indices i=1 and j=3 (indexed from 0), you will get the maximum value of (5-1)*(5-1) = 16. Example 3:

Input: nums = [3,7] Output: 12

/**
* @param {number[]} nums
* @return {number}
*/
var maxProduct = function (nums) {
nums.sort((a, b) => a - b);
const len = nums.length;
return (nums[len - 1] - 1) * (nums[len - 2] - 1);
};

Zsh Setup

· One min read
Shi Xinyu
Front End Developer

Here is my Zsh Setting.

~/.zshrc

export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion" # This loads nvm bash_completion

autoload -Uz vcs_info
precmd() { vcs_info }
zstyle ':vcs_info:git:*' formats '(%b)'
setopt PROMPT_SUBST
PROMPT='%n in ${PWD/#$HOME/~} %F{green}${vcs_info_msg_0_} %F{reset_color}> '