03.数组中重复的数字
找重复数字使用集合的思想,因为是函数,所以不要忘记return返回值。
has() 方法返回一个布尔值来指示对应的值 value 是否存在 Set 对象中。
var findRepeatNumber = function(nums) {
var newSet = new Set();
for(var i =0;i<nums.length;i++){
if(newSet.has(nums[i])){
return nums[i]
} else{
newSet.add(nums[i])
}
}
};
04.二维数组中查找
二维数组,采用坐标的思想,先定义矩阵的行和列,然后定义x、y的坐标轴,通过坐标来找值。
坑:要判断是否原数组为空数组;要注意区间的开闭;在判断与target的大小比较时,不要忘记等于的情况
var findNumberIn2DArray = function (matrix, target) {
var row = matrix.length;
var col = matrix[0].length;
if (row == 0) return false;
if (col == 0) return false;//表明数组里有数
var x =0;
var y = col-1;
while (x >= 0 && x <row && y < col && y >= 0){
if (matrix[x][y] == target) return true;
if (matrix[x][y] > target) {
y--;
} else {
x++;
}
}
//如果没进循环表明数字不在里面
return false;
}
05.替换空格
简单题先实现再说,后期再想简单方法
/**
* @param {string} s
* @return {string}
*/
var replaceSpace = function(s) {
var newStr = new String();
for(var i = 0; i<s.length;i++){
if(s[i] == ' '){
newStr +='%20';
}else{
newStr += s[i];
}
}
return newStr;
};
06.从尾到头打印链表
补充概念:
关于链表的一些基础概念,需要大补T^T
刚开始玩,只知道数组和栈的方法,数组太慢了,先取出链表中的值,然后存入数组,在对数组进行倒序输出,太慢太慢。栈稍微方便一些,它的特点是先入后出,所以先push压入栈,然后pop弹出栈。
在出栈的时候,判断stack情况的时候,用length!!length!! length!!重要的说三遍!!
/**
* Definition for singly-linked list.
* function ListNode(val) {
* this.val = val;
* this.next = null;
* }
*/
/**
* @param {ListNode} head
* @return {number[]}
*/
var reversePrint = function(head) {
var newArry = [];
var carry = head;
var stack = [];
while(carry){
stack.push(carry.val);
carry = carry.next;
};
while(stack.length){
newArry.push(stack.pop())
}
return newArry;
};
18.删除链表的结点
本题分为两个步骤:先是定位到需要删除的节点处,随后修改引用
1)定位节点:遍历链表,直到当前节点的val值与需要删除的目标节点的val值一致时跳出循环---->定位到目标节点
2)修改引用:若当前节点为cur,它的前节点为pre,后节点为cur.next;当执行pre.next = cur.next----删除cur节点
/**
* Definition for singly-linked list.
* function ListNode(val) {
* this.val = val;
* this.next = null;
* }
*/
/**
* @param {ListNode} head
* @param {number} val
* @return {ListNode}
*/
var deleteNode = function(head, val) {
var newHead = new ListNode();
newHead.next = head;
var pre = newHead;
var cur = head;
while(cur){
if(cur.val == val){
pre.next = cur.next;
cur.next = null;
break;
};
cur = cur.next;
pre = pre.next;
}
return newHead.next
};
22.链表中倒数第K个节点
使用双指针中的快慢指针,本题思路:定义两个指针,slow与fast,让fast先走到k,此时,fast指向k+1,slow指向head,两个指针差k step,然后两个指针一起出发,当fast指向Null的时候,表明已经到链表尾部,而此时slow也到了指定位置,输出slow即可,需要注意当指针为null的情况。
/**
* Definition for singly-linked list.
* function ListNode(val) {
* this.val = val;
* this.next = null;
* }
*/
/**
* @param {ListNode} head
* @param {number} k
* @return {ListNode}
*/
var getKthFromEnd = function(head, k) {
//快慢指针
if (head=== null) return null;
let slow = head;
let fast = head;
while(k>0 && fast != null){
fast = fast.next;
k--;
}
while(fast != null){
fast = fast.next;
slow = slow.next;
}
return slow;
};
24.反转链表
07.重建二叉树
基础知识:
pre-order:中-左-右;
in-order:左-中-右;
post-order:左-右-中;
**findIndex()**方法返回数组中第一次出现该元素地方的索引。若没有找到则返回-1。
slice() 方法返回一个新的数组对象,这一对象是一个由 begin 和 end 决定的原数组的浅拷贝(包括 begin,不包括end)。原始数组不会被改变。
先要考虑万一pre-order与in-order都是length=0呢,这不就是null了嘛
/**
* Definition for a binary tree node.
* function TreeNode(val) {
* this.val = val;
* this.left = this.right = null;
* }
*/
/**
* @param {number[]} preorder
* @param {number[]} inorder
* @return {TreeNode}
*/
var buildTree = function(preorder, inorder) {
if(preorder.length==0 || inorder.length ==0) return null;
//找到根节点
const index = inorder.findIndex(item => item === preorder[0]);
const left = inorder.slice(0,index);
const right = inorder.slice(index+1);
return{
val:preorder[0],
left:buildTree(preorder.slice(1,index+1),left),
right:buildTree(preorder.slice(index+1),right)
}
};
09用两个栈实现队列
10-1斐波那契数列
10-2青蛙跳台阶问题
矩阵中的路径
/**
* @param {character[][]} board
* @param {string} word
* @return {boolean}
*/
var exist = function(board, word) {
/*
1. dfs回溯法
让矩阵的每个位置都匹配下word,一旦成功就返回
2. 搜索结束边界判断
k=word.length和 矩阵边界检查 前后关系
*/
if(!board || !board.length) return false;
let col = board[0].length;
let row = board.length;
//遍历矩阵,让str从矩阵的00开始找,一旦找到则返回,
// 不一定字符就和[0,0]相同
// bfce
for(let i = 0; i< row;i++){
for(let j = 0;j<col;j++){
//让矩阵的每个位置都匹配下word(从第一个字符开始)
if(dfsHelper(board,word,i,j,0)){
return true;
}
}
}
return false;
};
//k是代表word的索引
function dfsHelper(board,word,i,j,k){
//中止条件,先检查是不是word已经匹配完成
//必须放检查4个边界前边
if(k== word.length) return true;
//检查4个边界
if(i>= board.length || j >= board[0].length || j<0 || i < 0) return false;
//如果char和当前矩阵不同,则返回false
//递归是为ture还要继续,false才返回
if(word.charAt(k) !== board[i][j]) return false;
let old = board[i][j];
board[i][j] = '0';
//查询子树,找下一个字符k+1
let re = dfsHelper(board,word,i,j+1,k+1)||
dfsHelper(board,word,i+1,j,k+1)||
dfsHelper(board,word,i,j-1,k+1)||
dfsHelper(board,word,i-1,j,k+1);
board[i][j] = old;
return re;//结果是子树的结果(k=word.length)
};