Fundamentals 18 min read

Decode Chinese ID Cards & Solve Classic LeetCode Problems with JavaScript

This article explains how to parse Chinese ID numbers to extract gender and age, demonstrates the checksum calculation, and then walks through classic algorithm challenges—including climbing stairs, longest palindrome, trapping rain water, and greedy cookie allocation—providing clear JavaScript implementations for each.

WeDoctor Frontend Technology
WeDoctor Frontend Technology
WeDoctor Frontend Technology
Decode Chinese ID Cards & Solve Classic LeetCode Problems with JavaScript

Calculate Gender and Age from a Chinese ID Number

The national standard GB11643‑1999 defines a citizen ID as a 17‑digit body code followed by a checksum digit. The structure consists of a six‑digit address code, an eight‑digit birth‑date code, a three‑digit sequence code, and a final checksum.

Address Code

Identifies the administrative region of the holder's permanent residence.

Birth‑Date Code

Encodes the holder's year, month, and day of birth.

Sequence Code

Orders individuals born on the same day in the same region; odd numbers denote males, even numbers denote females.

Checksum Calculation

The checksum is derived from the first 17 digits using ISO 7064:1983.MOD 11‑2. Compute the weighted sum S = Σ(Ai × Wi) where the weight factors are 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2. For the example ID 11010519491231002X, S = 167, Y = S mod 11 = 2, and the corresponding checksum digit is X.

<code>const WEIGHT = [7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2];
const MOD = [1,0,'X',9,8,7,6,5,4,3,2];
function isRightId(id){
  const arr = id.split('');
  const check = arr.pop();
  let sum = 0;
  arr.forEach((d,i)=> sum += d * WEIGHT[i]);
  const m = sum % 11;
  return MOD[m] + '' === check;
}
console.log(isRightId('11010519491231002X')); // true
console.log(isRightId('110105194912310029')); // false</code>

Deriving Age

<code>function getAge(id){
  const year = id.substr(6,4);
  const month = id.substr(10,2);
  const day = id.substr(12,2);
  const birth = new Date(`${year}/${month}/${day}`).getTime();
  const now = Date.now();
  const diff = now - birth;
  const days = diff / (24*60*60*1000);
  if(days < 31) return parseInt(days) + '天';
  if(days < 365) return `${parseInt(days/30)}月${parseInt(days%30)}天`;
  return `${parseInt(days/365)}岁${parseInt(days%365/30)}月${parseInt(days%365%30)}天`;
}
console.log(getAge('11010519491231002X')); // 71岁8月16天</code>

Deriving Gender

<code>function getSex(id){
  const sex = id.substr(16,1);
  return sex % 2 ? '男' : '女';
}
console.log(getSex('11010519491231002X')); // 女
console.log(getSex('11010520210820001X')); // 男</code>

Dynamic Programming Basics

Dynamic programming (DP) optimizes recursive solutions by storing intermediate results. The key is defining recurrence relations and boundary conditions.

Climbing Stairs (Easy)

<code>var climbStairs = function(n){
  let dp = [1,1];
  for(let i=2;i<=n;i++) dp[i] = dp[i-1] + dp[i-2];
  return dp[n];
};</code>

Longest Palindromic Substring (Medium)

<code>function longestPalindrome(s){
  const n = s.length;
  if(n<2) return s;
  let maxLen = 1, begin = 0;
  const dp = Array.from({length:n},()=>Array(n).fill(false));
  for(let i=0;i<n;i++) dp[i][i]=true;
  const chars = s.split('');
  for(let L=2; L<=n; L++){
    for(let i=0;i<n;i++){
      const j = i+L-1;
      if(j>=n) break;
      if(chars[i]!==chars[j]) dp[i][j]=false;
      else dp[i][j] = (j-i<3) ? true : dp[i+1][j-1];
      if(dp[i][j] && L>maxLen){ maxLen=L; begin=i; }
    }
  }
  return s.substring(begin, begin+maxLen);
}
console.log(longestPalindrome('babad'));
console.log(longestPalindrome('cbbd'));</code>

Trapping Rain Water (Hard)

<code>function trap(height){
  const n = height.length;
  if(n<=2) return 0;
  const leftMax = [], rightMax = [];
  leftMax[0]=height[0];
  for(let i=1;i<n;i++) leftMax[i]=Math.max(height[i], leftMax[i-1]);
  rightMax[n-1]=height[n-1];
  for(let i=n-2;i>=0;i--) rightMax[i]=Math.max(height[i], rightMax[i+1]);
  let sum=0;
  for(let i=0;i<n;i++) sum+=Math.min(leftMax[i], rightMax[i]) - height[i];
  return sum;
}
console.log(trap([0,1,0,2,1,0,1,3,2,1,2,1])); // 6</code>

Greedy Algorithms

A greedy algorithm makes the locally optimal choice at each step with the hope of finding a global optimum.

Assign Cookies

<code>function findContentChildren(children, cookies){
  children.sort((a,b)=>a-b);
  cookies.sort((a,b)=>a-b);
  let i=0, j=0, count=0;
  while(i<children.length && j<cookies.length){
    if(cookies[j] >= children[i]){ count++; i++; j++; }
    else j++;
  }
  return count;
}
console.log(findContentChildren([1,2,3],[1,1])); // 1
console.log(findContentChildren([1,2],[1,2,3])); // 2</code>

Best Time to Buy and Sell Stock with Transaction Fee

<code>function maxProfit(prices, fee){
  let buy = prices[0] + fee;
  let profit = 0;
  for(let i=1;i<prices.length;i++){
    if(prices[i] + fee < buy) buy = prices[i] + fee;
    else if(prices[i] > buy){ profit += prices[i] - buy; buy = prices[i]; }
  }
  return profit;
}
console.log(maxProfit([1,3,2,8,4,9],2)); // 8
console.log(maxProfit([1,3,7,5,10,3],3)); // 6</code>

Couples Holding Hands

<code>function minSwapsCouples(row){
  const pos = {};
  row.forEach((p,i)=> pos[p]=i);
  let ans=0;
  for(let i=0;i<row.length;i+=2){
    const lover = row[i]^1;
    if(pos[lover]!==i+1){
      ans++;
      const partnerIdx = pos[lover];
      // swap row[i+1] and row[partnerIdx]
      [row[i+1], row[partnerIdx]] = [row[partnerIdx], row[i+1]];
      pos[row[partnerIdx]] = partnerIdx;
      pos[lover] = i+1;
    }
  }
  return ans;
}
console.log(minSwapsCouples([0,2,1,3])); // 1
console.log(minSwapsCouples([3,2,0,1])); // 0</code>
javascriptdynamic programmingLeetCodealgorithmsGreedy
WeDoctor Frontend Technology
Written by

WeDoctor Frontend Technology

Official WeDoctor Group frontend public account, sharing original tech articles, events, job postings, and occasional daily updates from our tech team.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.