保定网站建设公司网站流量
79. 单词搜索
题目链接:79. 单词搜索
难度:中等
刷题状态:1刷
新知识:
解题过程
思考
示例 1:
输入:board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], word = "ABCCED" 输出:true
没思路,看答案
题解分析
参考题解链接:79. 单词搜索(回溯,清晰图解)
详细分析如下
/*** @param {character[][]} board* @param {string} word* @return {boolean}*/
var exist = function(board, word) {//定义函数dfs来判断是否有function dfs(i,j,start){//边界条件以及当前字符是否匹配,有一个不匹配的就返回错误if(i<0||i>=board.length||j<0||j>=board[0].length||board[i][j]!=word[start]) return falseif(start==word.length-1) return true//临时标记当前格子为访问过(避免重复使用)let tmp=board[i][j]board[i][j]=''//遍历上下左右四个方向let res=dfs(i+1,j,start+1)||dfs(i-1,j,start+1)||dfs(i,j+1,start+1)||dfs(i,j-1,start+1)//恢复当前格子的的值board[i][j]=tmpreturn res}//遍历每个格子,尝试从每个格子开始搜索(不同的start)for (let i=0;i<board.length;i++){for(let j=0;j<board[0].length;j++){if(dfs(i,j,0)) return true}}return false
};
手搓答案(无非废话版)
/*** @param {character[][]} board* @param {string} word* @return {boolean}*/var exist=function(board,word){function dfs(i,j,start){if(i<0||i>=board.length||j<0||j>=board[0].length||board[i][j]!=word[start]) return falseif(start==word.length-1) return truelet tmp=board[i][j]board[i][j]=''let res=dfs(i+1,j,start+1)||dfs(i-1,j,start+1)||dfs(i,j+1,start+1)||dfs(i,j-1,start+1)board[i][j]=tmpreturn res}for(let i=0;i<board.length;i++){for(let j=0;j<board[0].length;j++){if(dfs(i,j,0)) return true}}return false}
总结
注意边界条件的设置,一步一步来解就行
131. 分割回文串
题目链接:131. 分割回文串
难度:中等
刷题状态:2刷
新知识:
- `s.substring(start,end+1)` 用于提取字符串中部分内容的内置方法
解题过程
思考
示例 1:
输入:s = "aab" 输出:[["a","a","b"],["aa","b"]]
题解分析
参考题解链接:【视频】回溯不会写?套路在此!(Python/Java/C++/Go/JS)
放下1刷过程
/*** @param {string} s* @return {string[][]}*/
// var partition = function(s) {
// let n=s.length//3
// let res=[]//结果
// let path=[]//一条可行的路
// //这个函数判断字符串s从索引left到right的子串是否为回文
// //这里还是很好理解的
// function isPalindrome(s,left,right){
// while(left<right){
// if(s.charAt(left)!=s.charAt(right)){
// return false
// }
// left++
// right--
// //可以简写为如下,但我习惯上面的写法
// // if(s.charAt(left++)!=s.charAt(right--)){
// // return false
// // }
// }
// return true
// }
// // 上一个已经确定的回文子串的结束位置是 start
// // i表示当前考虑到字符串s中的第 i 个字符
// function dfs(start,i){
// if(i==n){
// //处理到最后一个字符了
// // path存储一下,再复制到res中
// res.push(path.slice())
// console.log('res',res)
// return
// }
// //下面这个是为了先找到s中最长的回文子串 aa,然后再一点点减小长度,直到出现最小单位的子串集,比如 a a b
// if(i<n-1){
// console.log('i<n-1',i)
// dfs(start,i+1)
// }
// console.log(start,i)
// console.log('isPalindrome(s,start,i)',isPalindrome(s,start,i))
// if(isPalindrome(s,start,i)){
// //是回文,加到path中
// path.push(s.substring(start,i+1))
// console.log('path',path)
// dfs(i+1,i+1)//下一个子串从i+1开始
// path.pop()//移除刚加入的子串,恢复现场
// }
// }
// dfs(0,0)
// return res
// };var partition = function(s) {let n=s.lengthlet res=[]let path=[]function isHuiwen(s,left,right){while(left<right){if(s.charAt(left++)!=s.charAt(right--)){return false}}return true}function dfs(start,i){if(i==n){res.push(path.slice())return }if(i<n-1){dfs(start,i+1)}if(isHuiwen(s,start,i)){path.push(s.substring(start,i+1))dfs(i+1,i+1)path.pop()}}dfs(0,0)return res
}
手搓答案(无非废话版)
/*** @param {string} s* @return {string[][]}*/var partition=function(s){let n=s.lengthlet path=[],res=[]function isHuiwen(left,right){while(left<right){if(s[left]!=s[right]) return falseleft++right--}return true}function dfs(start){if(start==n){res.push([...path])return}for(let end=start;end<n;end++){if(isHuiwen(start,end)){path.push(s.substring(start,end+1))dfs(end+1)path.pop()}}}dfs(0)return res}
总结
这里修改了dfs函数的逻辑,实现同样的效果
51. N 皇后
题目链接:51. N 皇后
难度:困难
刷题状态:1刷
新知识:
解题过程
思考
示例 1:
输入:n = 4 输出:[[".Q..","...Q","Q...","..Q."],["..Q.","Q...","...Q",".Q.."]] 解释:如上图所示,4 皇后问题存在两个不同的解法。
没思路,看答案
题解分析
参考题解链接:【视频讲解】排列型回溯,简洁高效!(Python/Java/C++/C/Go/JS/Rust)
放下1刷过程
/*** @param {number} n* @return {string[][]}*/
// var solveNQueens = function(n) {
// let res=[]
// // 存储每一行皇后的列位置,r行 col[r]列 [r,col[r]]是皇后的坐标
// let col=Array(n).fill(0)
// // 判断该列是否被用过
// let usedCol=new Array(n).fill(false)
// //该函数用来判断,对角线是否被占领
// function vaild(r,c){
// //r以上的行
// for(let R=0;R<r;R++){
// let C=col[R]
// //[R,C]是r以上的行的皇后的位置
// if (r+c==R+C||r-c==R-C) return false
// }
// return true
// }
// function dfs(r){
// //处理完最后一行了
// if(r==n){
// //生成棋盘表示
// let board=[]
// for(let c of col){
// board.push('.'.repeat(c)+'Q'+'.'.repeat(n-1-c))
// }
// res.push(board)
// return
// }
// //循环列,找到每行皇后可能在的列
// for(let c=0;c<n;c++){
// if(!usedCol[c]){
// if(vaild(r,c)){
// col[r]=c
// usedCol[c]=true
// dfs(r+1)
// usedCol[c]=false
// col[r]=0
// }
// }
// }// }
// dfs(0)
// return res
// }var solveNQueens = function(n) {let res=[]let col=new Array(n).fill(0)let usedCol=new Array(n).fill(false)function valid(r,c){for(let R=0;R<r;R++){let C=col[R]if(R+C==r+c||R-C==r-c) return false}return true}function dfs(r){if(r==n){let board=[]for(let c of col){board.push('.'.repeat(c)+'Q'+'.'.repeat(n-1-c))}res.push(board)return}for(let c=0;c<n;c++){if(!usedCol[c]){if(valid(r,c)){col[r]=cusedCol[c]=truedfs(r+1)usedCol[c]=falsecol[r]=0}}}}dfs(0)return res
}
手搓答案(无非废话版)
/*** @param {number} n* @return {string[][]}*/var solveNQueens=function(n){let res=[]let col=new Array(n).fill(0)let usedCol=new Array(n).fill(false)function dfs(r){if(r==n){let board=[]for(let c of col){board.push('.'.repeat(c)+'Q'+'.'.repeat(n-1-c))}res.push(board)return }for(let c=0;c<n;c++){if(!usedCol[c]){if(isnoX(r,c)){col[r]=cusedCol[c]=truedfs(r+1)usedCol[c]=falsecol[r]=0}}}}function isnoX(R,C){for(let r=0;r<R;r++){let c=col[r]if(r+c==R+C||r-c==R-C) return false}return true}dfs(0)return res}
总结
注意 if(r+c==R+C||r-c==R-c) return false
- 这行代码检查当前行
r
的皇后位置(r, c)
是否与之前的某一行R
的皇后位置(R, col[R])
在同一条对角线上。 r + c == R + col[R]
检查两个皇后是否在同一主对角线(从左上到右下)。r - c == R - col[R]
检查两个皇后是否在同一副对角线(从右上到左下)。
35. 搜索插入位置
题目链接:35. 搜索插入位置
难度:简单
刷题状态:1刷
新知识:
解题过程
思考
示例 1:
输入: nums = [1,3,5,6], target = 5 输出: 2
题解分析
参考题解链接:画解算法:35. 搜索插入位置
详细分析如下
class Solution {searchInsert(nums, target) {let left = 0, right = nums.length - 1; // 初始化左右指针while (left <= right) { // 当左指针小于等于右指针时继续循环let mid = Math.floor((left + right) / 2); // 计算中间索引,使用 Math.floor 确保为整数if (nums[mid] === target) { // 如果中间元素等于目标值// 找到目标值,可以返回索引或进行其他逻辑处理return mid;} else if (nums[mid] < target) {left = mid + 1; // 如果中间元素小于目标值,移动左指针} else {right = mid - 1; // 如果中间元素大于目标值,移动右指针}}// 如果没有找到目标值,返回左指针作为插入位置return left;}
}// 示例用法
const solution = new Solution();
const nums = [1, 3, 5, 6];
const target = 5;
console.log(solution.searchInsert(nums, target)); // 输出: 2const target2 = 2;
console.log(solution.searchInsert(nums, target2)); // 输出: 1const target3 = 7;
console.log(solution.searchInsert(nums, target3)); // 输出: 4
手搓答案(无非废话版)
/*** @param {number[]} nums* @param {number} target* @return {number}*/
var searchInsert = function(nums, target) {let left=0,right=nums.length-1while(left<=right){let mid=((right-left)>>1)+leftif(nums[mid]<target){left=mid+1}else{right=mid-1}}return left
};
总结
简单
74. 搜索二维矩阵
题目链接:74. 搜索二维矩阵
难度:中等
刷题状态:1刷
新知识:
解题过程
思考
示例 1:
输入:matrix = [[1,3,5,7],[10,11,16,20],[23,30,34,60]], target = 3 输出:true
没思路,看答案
题解分析
参考题解链接:两种方法:二分查找/排除法(Python/Java/C++/C/Go/JS/Rust)
详细分析如下
var searchMatrix = function(matrix, target) {const m = matrix.length, n = matrix[0].length;let left = -1, right = m * n;while (left + 1 < right) {const mid = Math.floor((left + right) / 2);const x = matrix[Math.floor(mid / n)][mid % n];if (x === target) {return true;}if (x < target) {left = mid;} else {right = mid;}}return false;
};
手搓答案(无非废话版)
/*** @param {number[][]} matrix* @param {number} target* @return {boolean}*/
var searchMatrix = function(matrix, target) {let m=matrix.length,n=matrix[0].lengthlet left=0,right=m*n-1while(left<=right){let mid=((right-left)>>1)+leftM=matrix[Math.floor(mid/n)][mid%n]if(M==target) return trueif(M<target){left=mid+1}else{right=mid-1}}return false
};
总结
注意这一行是怎么表示二维数组的位置M=matrix[Math.floor(mid/n)][mid%n]