前端面试汇总大全—剑指offer刷题—js牛客网刷题
作者:互联网
1, 二维数组中的查找
function Find(target, array) {
const n = array.length,
m = array[0].length;
let row = n - 1,
col = 0;
if (m === 0 && n === 0) {
return false;
}
while (row >= 0 && col <= m - 1) {
if (array[row][col] > target) {
row--;
} else if (array[row][col] < target) {
col++;
} else return true;
}
return false;
}
2, 替换空格
function replaceSpace(str) {
return str.replace(/\s/g, '%20'); // \s 匹配任意的空白符
}
3, 从头到尾打印链表
/* function ListNode(x){
this.val = x;
this.next = null;
}*/
function printListFromTailToHead(head) {
// write code here
const res = [];
let pNode = head;
while (pNode !== null) {
res.unshift(pNode.val);
pNode = pNode.next;
}
return res;
}
4, 重建二叉树
/* function TreeNode(x) {
this.val = x;
this.left = null;
this.right = null;
} */
function reConstructBinaryTree(pre, vin) {
if (pre.length === 0 || vin.length === 0) { return null; }
// 前序第一个是根节点,也是中序左右子树的分割点
const index = vin.indexOf(pre[0]),
left = vin.slice(0, index),
right = vin.slice(index + 1);
return {
val: pre[0], // 递归左右子树的前序、中序
left: reConstructBinaryTree(pre.slice(1, index + 1), left),
right: reConstructBinaryTree(pre.slice(index + 1), right)
};
}
5, 用两个栈实现队列
const outStack = [],
inStack = [];
function push(node) {
// write code here
inStack.push(node);
}
function pop() {
// write code here
if (!outStack.length) {
while (inStack.length) {
outStack.push(inStack.pop());
}
}
return outStack.pop();
}
6, 旋转数组中的最小数字
// 第一种
function minNumberInRotateArray1(rotateArray) {
// write code here
if (rotateArray.length === 0) return 0;
for (let i = 0; i < rotateArray.length; i++) {
if (rotateArray[i] > rotateArray[i + 1]) return rotateArray[i + 1];
}
return rotateArray[0];
}
// 第二种
function minNumberInRotateArray2(rotateArray) {
let left = 0,
right = rotateArray.length - 1;
while (right - left > 1) {
let mid = left + (right - left) >> 1;
mid = left + (right - left >> 1);
if (rotateArray[mid] > rotateArray[right]) {
left = mid;
} else {
right = mid;
}
}
return Math.min(rotateArray[left], rotateArray[right]);
}
7, 斐波那契数列
function Fibonacci(n) {
let f = 0,
g = 1;
while (n--) {
g += f;
f = g - f;
}
return f;
}
8, 跳台阶
function jumpFloor(number) {
let f = 1,
g = 2;
while (--number) {
g += f;
f = g - f;
}
return f;
}
9, 变态跳台阶
function jumpFloorII(number) {
let i = 1;
while (--number) {
i *= 2;
}
return i;
}
10, 矩形覆盖
function rectCover(number) {
if (number === 0) return 0;
let f = 1,
g = 2;
while (--number) {
g += f;
f = g - f;
}
return f;
}
11, 二进制中1的个数
// 第一种
function NumberOf1(n) {
let count = 0,
flag = 1;
while (flag) {
// 循环的次数等于整数二进制的位数,32位的整数需要循环32位
if (flag & n) count++;
flag = flag << 1;
}
return count;
}
// 第二种
function newNumberOf1(n) {
let count = 0;
while (n) {
n = n & n - 1; // 核心
count++;
}
return count;
}
12, 数值的整数次方
function Power(base, exponent) {
let res = 1,
n;
if (exponent > 0) { // 指数大于0的情况下
n = exponent;
} else if (exponent < 0) { // 指数小于0的情况下
if (!base) throw new Error('分母不能为0');
n = -exponent;
} else { // 指数等于0的情况下
return 1;
}
while (n) { // 也可以用递归做,这里采用了循环
if (n & 1) // 当指数为奇数时,包括了1
res *= base;
base *= base;
n >>= 1;
}
return exponent > 0 ? res : 1 / res;
}
13, 调整数组顺序使奇数位于偶数前面
function reOrderArray(array) {
// oddBegin主要是用作奇数的索引,oddCount是用作偶数的索引,newArray用来存储,以空间换时间,复杂度为O(n)
let oddBegin = 0,
oddCount = 0;
const newArray = [];
for (let i = 0; i < array.length; i++) {
if (array[i] & 1) {
oddCount++;
}
}
for (let i = 0; i < array.length; i++) {
if (array[i] & 1) {
newArray[oddBegin++] = array[i];
} else {
newArray[oddCount++] = array[i];
}
}
return newArray;
}
14, 链表中倒数第K个结点
/* function ListNode(x){
this.val = x;
this.next = null;
}*/
function FindKthToTail(head, k) {
if (head === null || k <= 0) return null;
let pNode1 = head,
pNode2 = head;
while (--k) {
if (pNode2.next !== null) {
pNode2 = pNode2.next;
} else {
return null;
}
}
while (pNode2.next !== null) {
pNode1 = pNode1.next;
pNode2 = pNode2.next;
}
return pNode1;
}
15, 反转链表
/* function ListNode(x){
this.val = x;
this.next = null;
}*/
function ReverseList(pHead) {
// write code here
let pPre = null,
pNext = null;
while (pHead !== null) {
pNext = pHead.next;
pHead.next = pPre;
pPre = pHead;
pHead = pNext;
}
return pPre;
}
16, 合并两个排序的链表
/* function ListNode(x){
this.val = x;
this.next = null;
}*/
function Merge(pHead1, pHead2) {
let pMergeHead = null;
// write code here
if (pHead1 === null) return pHead2;
if (pHead2 === null) return pHead1;
if (pHead1.val < pHead2.val) {
pMergeHead = pHead1;
pMergeHead.next = Merge(pHead1.next, pHead2);
} else {
pMergeHead = pHead2;
pMergeHead.next = Merge(pHead1, pHead2.next);
}
return pMergeHead;
}
30, 连续子数组和的最大值
function FindGreatestSumOfSubArray(array) {
if (array.length <= 0) return 0;
let sum = array[0],
max = array[0];
for (let i = 1; i < array.length; i++) {
if (sum < 0) sum = array[i];
else sum = sum + array[i];
if (sum > max) max = sum;
}
return max;
}
31, 1~n整数中1出现的次数
是按位取反的意思,~就是再转回来,两个按位取反,类型的转换成数字符号。
// 暴力解法
function NumberOf1Between1AndNSolution(n) {
let ones = 0;
for (let i = 0; i <= n; i++) {
let num = i;
while (num) {
if (num % 10 === 1) {
ones++;
}
num = ~~(num / 10);
}
}
return ones;
}
// 优化版
function NumberOf1Between1AndNSolution2(n) {
if (n <= 0) return 0;
let count = 0;
for (let i = 1; i <= n; i *= 10) {
const a = ~~(n / i),
b = n % i;
count = count + ~~((a + 8) / 10) * i + (a % 10 === 1) * (b + 1);
}
return count;
}
34, 第一个只出现一次的字符
function FirstNotRepeatingChar(str) {
if (str.length < 1 || str.length > 10000) return -1;
const map = {};
for (let i = 0; i < str.length; i++) {
if (!map[str[i]]) {
map[str[i]] = 1;
} else {
map[str[i]]++;
}
}
for (let i = 0; i < str.length; i++) {
if (map[str[i]] === 1) {
return i;
}
}
return -1;
}
40, 数组中只出现一次的数字
// 第一种: indexOf是从前向后查 而lastIndexOf是从后向前查 但是二者返回索引都为下标
function FindNumsAppearOnce(array) {
const res = [];
for (let i = 0; i < array.length; i++) {
if (array.indexOf(array[i]) === array.lastIndexOf(array[i])) {
res.push(array[i]);
}
}
return res;
}
// 第二种
function FindNumsAppearOnce2(array) {
const map = {},
res = [];
for (let i = 0; i < array.length; i++) {
if (!map[array[i]]) {
map[array[i]] = 1;
} else {
map[array[i]]++;
}
}
for (let i = 0; i < array.length; i++) {
if (map[array[i]] === 1) {
res.push(array[i]);
}
}
return res;
}
// 第三种
function FindNumsAppearOnce3(array) {
let tmp = array[0];
for (let i = 1; i < array.length; i++) {
tmp = tmp ^ array[i];
}
if (tmp === 0) return;
let index = 0; // 记录第几位是1
while ((tmp & 1) === 0) {
tmp = tmp >> 1;
index++;
}
let num1 = 0,
num2 = 0;
for (let i = 0; i < array.length; i++) {
if (isOneAtIndex(array[i], index)) num1 = num1 ^ array[i];
else num2 = num2 ^ array[i];
}
return [num1, num2];
}
function isOneAtIndex(num, index) {
num = num >> index;
return num & 1;
}
41, 和为S的字符串
假设序列的开始数字为a,结束数字为a+i,那么有(a+i-a+1)(a+a+i)/2=sum
也就是(i+1)(2a+i)=2sum,只需要找出这样的a和i就行,再根据a和i得出序列。
function FindContinuousSequence(sum) {
let a = 0,
half = sum >> 1;
const res = [];
while (half--) {
a++;
let i = 1;
while ((i + 1) * (2 * a + i) < 2 * sum) { i++; }
if ((i + 1) * (2 * a + i) === 2 * sum) {
const tmp = [];
tmp.push(a);
tmp.push(i);
res.push(tmp);
}
}
for (let i = 0; i < res.length; i++) {
let num = res[i][1],
k = 1;
const tmp = [];
tmp.push(res[i][0]);
while (num--) {
tmp.push(res[i][0] + k);
k++;
}
res[i] = tmp;
}
return res;
}
42, 和为S的字符串
function FindNumbersWithSum(array, sum) {
if (array.length < 2) return [];
let left = 0,
right = array.length - 1;
const res = [];
while (left < right) {
if (array[left] + array[right] < sum) {
left++;
} else if (array[left] + array[right] > sum) {
right--;
} else {
res.push(array[left], array[right]);
break;
}
}
return res;
}
44, 单词翻转序列
function ReverseSentence(str) {
return str
.split(' ')
.reverse()
.join(' ');
}
47, 求1+2+3+...+n
// 用右移运算符,再结合等差数列求和公式。
function Sum_Solution(n)
{
var res = Math.pow(n, 2) + n;
return res >> 1;
}
//第二种 逻辑运算的短路特性
function SumSolution(n) {
return n && Sum_Solution(n - 1) + n;
}
48, 不用加减乘除做加法
function Add(num1, num2) {
while (num2 !== 0) {
const tmp1 = num1 ^ num2;
num2 = (num1 & num2) << 1;
num1 = tmp1;
}
return num1;
}
49, 把字符串转换成整数
function StrToInt(str) {
let res = 0,
flag = 1;
const n = str.length;
if (!n) return 0;
if (str[0] === '-') {
flag = -1;
}
for (let i = str[0] === '+' || str[0] === '-' ? 1 : 0; i < n; i++) {
if (!(str[i] >= '0' && str[i] <= '9')) return 0;
res = (res << 1) + (res << 3) + (str[i] - '0');
}
return res * flag;
}
55,链表中环的入口节点
/* function ListNode(x){
this.val = x;
this.next = null;
}*/
function EntryNodeOfLoop(pHead) {
let fast = pHead;
let slow = pHead;
while (fast !== null && fast.next !== null) {
slow = slow.next;
fast = fast.next.next;
if (fast === slow) { // 两者相遇
let p = pHead;
while (p !== slow) {
p = p.next;
slow = slow.next;
}
return p;
}
}
return null;
}
Cookie_fzx
发布了82 篇原创文章 · 获赞 22 · 访问量 4万+
私信
关注
标签:function,return,offer,res,js,length,let,网刷题,array 来源: https://blog.csdn.net/image_fzx/article/details/103951258