From 1b94b77cbbfd13d96c66010a5312699e11c93a5a Mon Sep 17 00:00:00 2001 From: gaofer <35647389+gaofer@users.noreply.github.com> Date: Wed, 30 Aug 2023 05:21:47 +0800 Subject: [PATCH] Add code in javascript and typescript. (#690) * Add binary_search_insertion and binary_search_edge code in javascript and typescript. * code style fix: in FOR loop, use CONST will be nicer. * fix: Code Style * Change ==/!= to ===/!== * Create const by default, change to let if necessary. * Update import files * Update codes/javascript/chapter_searching/binary_search_edge.js Co-authored-by: Justin Tse * style fix: Delete unnecessary defined type --------- Co-authored-by: Justin Tse --- .../chapter_searching/binary_search_edge.js | 45 +++++++++++++ .../binary_search_insertion.js | 64 +++++++++++++++++++ .../chapter_searching/binary_search_edge.ts | 47 ++++++++++++++ .../binary_search_insertion.ts | 62 ++++++++++++++++++ 4 files changed, 218 insertions(+) create mode 100644 codes/javascript/chapter_searching/binary_search_edge.js create mode 100644 codes/javascript/chapter_searching/binary_search_insertion.js create mode 100644 codes/typescript/chapter_searching/binary_search_edge.ts create mode 100644 codes/typescript/chapter_searching/binary_search_insertion.ts diff --git a/codes/javascript/chapter_searching/binary_search_edge.js b/codes/javascript/chapter_searching/binary_search_edge.js new file mode 100644 index 000000000..30dcb5a20 --- /dev/null +++ b/codes/javascript/chapter_searching/binary_search_edge.js @@ -0,0 +1,45 @@ +/** + * File: binary_search_edge.js + * Created Time: 2023-08-22 + * Author: Gaofer Chou (gaofer-chou@qq.com) + */ + +const { binarySearchInsertion } = require('./binary_search_insertion.js'); + +/* 二分查找最左一个 target */ +function binarySearchLeftEdge(nums, target) { + // 等价于查找 target 的插入点 + const i = binarySearchInsertion(nums, target); + // 未找到 target ,返回 -1 + if (i === nums.length || nums[i] !== target) { + return -1; + } + // 找到 target ,返回索引 i + return i; +} + +/* 二分查找最右一个 target */ +function binarySearchRightEdge(nums, target) { + // 转化为查找最左一个 target + 1 + const i = binarySearchInsertion(nums, target + 1); + // j 指向最右一个 target ,i 指向首个大于 target 的元素 + const j = i - 1; + // 未找到 target ,返回 -1 + if (j === -1 || nums[j] !== target) { + return -1; + } + // 找到 target ,返回索引 j + return j; +} + +/* Driver Code */ +// 包含重复元素的数组 +const nums = [1, 3, 6, 6, 6, 6, 6, 10, 12, 15]; +console.log('\n数组 nums = ' + nums); +// 二分查找左边界和右边界 +for (const target of [6, 7]) { + let index = binarySearchLeftEdge(nums, target); + console.log('最左一个元素 ' + target + ' 的索引为 ' + index); + index = binarySearchRightEdge(nums, target); + console.log('最右一个元素 ' + target + ' 的索引为 ' + index); +} diff --git a/codes/javascript/chapter_searching/binary_search_insertion.js b/codes/javascript/chapter_searching/binary_search_insertion.js new file mode 100644 index 000000000..994f7f779 --- /dev/null +++ b/codes/javascript/chapter_searching/binary_search_insertion.js @@ -0,0 +1,64 @@ +/** + * File: binary_search_insertion.js + * Created Time: 2023-08-22 + * Author: Gaofer Chou (gaofer-chou@qq.com) + */ + +/* 二分查找插入点(无重复元素) */ +function binarySearchInsertionSimple(nums, target) { + let i = 0, + j = nums.length - 1; // 初始化双闭区间 [0, n-1] + while (i <= j) { + const m = Math.floor(i + (j - i) / 2); // 计算中点索引 m, 使用 Math.floor() 向下取整 + if (nums[m] < target) { + i = m + 1; // target 在区间 [m+1, j] 中 + } else if (nums[m] > target) { + j = m - 1; // target 在区间 [i, m-1] 中 + } else { + return m; // 找到 target ,返回插入点 m + } + } + // 未找到 target ,返回插入点 i + return i; +} + +/* 二分查找插入点(存在重复元素) */ +function binarySearchInsertion(nums, target) { + let i = 0, + j = nums.length - 1; // 初始化双闭区间 [0, n-1] + while (i <= j) { + const m = Math.floor(i + (j - i) / 2); // 计算中点索引 m, 使用 Math.floor() 向下取整 + if (nums[m] < target) { + i = m + 1; // target 在区间 [m+1, j] 中 + } else if (nums[m] > target) { + j = m - 1; // target 在区间 [i, m-1] 中 + } else { + j = m - 1; // 首个小于 target 的元素在区间 [i, m-1] 中 + } + } + // 返回插入点 i + return i; +} + +/* Driver Code */ +// 无重复元素的数组 +let nums = [1, 3, 6, 8, 12, 15, 23, 26, 31, 35]; +console.log('\n数组 nums = ' + nums); +// 二分查找插入点 +for (const target of [6, 9]) { + const index = binarySearchInsertionSimple(nums, target); + console.log('元素 ' + target + ' 的插入点的索引为 ' + index); +} + +// 包含重复元素的数组 +nums = [1, 3, 6, 6, 6, 6, 6, 10, 12, 15]; +console.log('\n数组 nums = ' + nums); +// 二分查找插入点 +for (const target of [2, 6, 20]) { + const index = binarySearchInsertion(nums, target); + console.log('元素 ' + target + ' 的插入点的索引为 ' + index); +} + +module.exports = { + binarySearchInsertion +}; \ No newline at end of file diff --git a/codes/typescript/chapter_searching/binary_search_edge.ts b/codes/typescript/chapter_searching/binary_search_edge.ts new file mode 100644 index 000000000..704ed823a --- /dev/null +++ b/codes/typescript/chapter_searching/binary_search_edge.ts @@ -0,0 +1,47 @@ +/** + * File: binary_search_edge.ts + * Created Time: 2023-08-22 + * Author: Gaofer Chou (gaofer-chou@qq.com) + */ +import { binarySearchInsertion } from './binary_search_insertion'; + + +/* 二分查找最左一个 target */ +function binarySearchLeftEdge(nums: Array, target: number): number { + // 等价于查找 target 的插入点 + const i = binarySearchInsertion(nums, target); + // 未找到 target ,返回 -1 + if (i === nums.length || nums[i] !== target) { + return -1; + } + // 找到 target ,返回索引 i + return i; +} + +/* 二分查找最右一个 target */ +function binarySearchRightEdge(nums: Array, target: number): number { + // 转化为查找最左一个 target + 1 + const i = binarySearchInsertion(nums, target + 1); + // j 指向最右一个 target ,i 指向首个大于 target 的元素 + const j = i - 1; + // 未找到 target ,返回 -1 + if (j === -1 || nums[j] !== target) { + return -1; + } + // 找到 target ,返回索引 j + return j; +} + +/* Driver Code */ +// 包含重复元素的数组 +let nums= [1, 3, 6, 6, 6, 6, 6, 10, 12, 15]; +console.log('\n数组 nums = ' + nums); +// 二分查找左边界和右边界 +for (const target of [6, 7]) { + let index = binarySearchLeftEdge(nums, target); + console.log('最左一个元素 ' + target + ' 的索引为 ' + index); + index = binarySearchRightEdge(nums, target); + console.log('最右一个元素 ' + target + ' 的索引为 ' + index); +} + +export {}; diff --git a/codes/typescript/chapter_searching/binary_search_insertion.ts b/codes/typescript/chapter_searching/binary_search_insertion.ts new file mode 100644 index 000000000..19a1aea52 --- /dev/null +++ b/codes/typescript/chapter_searching/binary_search_insertion.ts @@ -0,0 +1,62 @@ +/** + * File: binary_search_insertion.ts + * Created Time: 2023-08-22 + * Author: Gaofer Chou (gaofer-chou@qq.com) + */ + +/* 二分查找插入点(无重复元素) */ +function binarySearchInsertionSimple(nums: Array, target: number): number { + let i = 0, + j = nums.length - 1; // 初始化双闭区间 [0, n-1] + while (i <= j) { + const m = Math.floor(i + (j - i) / 2); // 计算中点索引 m, 使用 Math.floor() 向下取整 + if (nums[m] < target) { + i = m + 1; // target 在区间 [m+1, j] 中 + } else if (nums[m] > target) { + j = m - 1; // target 在区间 [i, m-1] 中 + } else { + return m; // 找到 target ,返回插入点 m + } + } + // 未找到 target ,返回插入点 i + return i; +} + +/* 二分查找插入点(存在重复元素) */ +function binarySearchInsertion(nums: Array, target: number): number { + let i = 0, + j = nums.length - 1; // 初始化双闭区间 [0, n-1] + while (i <= j) { + const m = Math.floor(i + (j - i) / 2); // 计算中点索引 m, 使用 Math.floor() 向下取整 + if (nums[m] < target) { + i = m + 1; // target 在区间 [m+1, j] 中 + } else if (nums[m] > target) { + j = m - 1; // target 在区间 [i, m-1] 中 + } else { + j = m - 1; // 首个小于 target 的元素在区间 [i, m-1] 中 + } + } + // 返回插入点 i + return i; +} + +/* Driver Code */ +// 无重复元素的数组 +let nums = [1, 3, 6, 8, 12, 15, 23, 26, 31, 35]; +console.log('\n数组 nums = ' + nums); +// 二分查找插入点 +for (const target of [6, 9]) { + const index = binarySearchInsertionSimple(nums, target); + console.log('元素 ' + target + ' 的插入点的索引为 ' + index); +} + +// 包含重复元素的数组 +nums = [1, 3, 6, 6, 6, 6, 6, 10, 12, 15]; +console.log('\n数组 nums = ' + nums); +// 二分查找插入点 +for (const target of [2, 6, 20]) { + const index = binarySearchInsertion(nums, target); + console.log('元素 ' + target + ' 的插入点的索引为 ' + index); +} + +export { binarySearchInsertion };