单词搜索 & 周赛第二道
单词搜索
描述:
给定一个二维网格和一个单词,找出该单词是否存在于网格中。单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使用。
代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 | /** * @param {character[][]} board * @param {string} word * @return {boolean} */ var exist = function (board, word) { let l = board.length, rL = board[0].length, col = 0, row = 0, isUsed={}, start = [], first = true ; /** * 以 board[r][c]为中心查找 target */ function findIndex( r , c,target,index){ if ( first ){ for ( let i = r; i < l ; i++){ for ( let j = c; j < rL; j++){ if ( board[i][j] == target ){ // isUsed[i+'$'+j] =1; start.push({ row: i, col:j, }) } } } first = false ; if ( start.length !== 0) return true return false ; } else { let result = []; if ( c + 1 < rL){ if ( !isUsed[ r + '$' + ( c + 1 )] ) if ( board[r][c +1] == target ){ result.push({ row: r, col: c +1 }) } } if ( c - 1 >= 0 ){ if ( !isUsed[ r + '$' + ( c - 1 )] ) if ( board[r][c - 1] == target ){ result.push({ row: r, col: c - 1 }) } } if ( r + 1 < l){ if ( !isUsed[ ( r + 1) + '$' + ( c )] ) if ( board[r+1][c] == target ){ result.push({ row: r + 1, col: c }) } } if ( r - 1 >= 0){ if ( !isUsed[ ( r - 1) + '$' + ( c )] ) if ( board[r-1][c] == target ){ result.push({ row: r - 1, col: c }) } } if ( result.length == 0 ) return false if ( index == (word.length - 1 ) ) return true ; for ( let i = 0,l = result.length; i < l; i++){ let row = result[i].row, col = result[i].col; isUsed[ row + '$' + col ] = 1; if ( findIndex(row,col,word[++index],index )){ return true } else { // 查找下一个可能的路径时 原来没用的使用过的格子就是没用过的了,得清除一下。 isUsed[ row + '$' + col ] = 0; index--; } } } return false ; } if ( !findIndex( 0 ,0,word[0] ) ) // 找入口,结果保存在start里 return false if ( (word.length == 1) && (start.length !== 0 )) // word只有一个字符时的特殊处理 return true ; for ( let j = 0; j < start.length; j++ ){ isUsed = {}; isUsed[ start[j][ 'row' ] + '$' + start[j][ 'col' ] ] = true ; row = start[j][ 'row' ],col = start[j][ 'col' ]; if (findIndex( row ,col,word[1],1 )){ return true ; } } return false ; }; |
思路: 就是老实人的算法啦,老老实实找到入口,遍历入口,然后通过递归查找每一条可能的路径,当开始找word里最后一个元素时,如果此时路径集合 result不为空,则证明存在路径,值的一提的是,由于题目描述,一个元素的路径可以在其元素的上下左右四个方位出现,所以需要探索四个方位的路径,由于不能重复使用,所以需要有个标记标记一下,采用递归最好。
2. 水果成篮
在一排树中,第 i 棵树产生 tree[i] 型的水果。
你可以从你选择的任何树开始,然后重复执行以下步骤:把这棵树上的水果放进你的篮子里。如果你做不到,就停下来。
移动到当前树右侧的下一棵树。如果右边没有树,就停下来。
请注意,在选择一颗树后,你没有任何选择:你必须执行步骤 1,然后执行步骤 2,然后返回步骤 1,然后执行步骤 2,依此类推,直至停止。
你有两个篮子,每个篮子可以携带任何数量的水果,但你希望每个篮子只携带一种类型的水果。
用这个程序你能收集的水果总量是多少?
代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | /** * @param {number[]} tree * @return {number} */ var totalFruit = function (tree) { let start= leftBasket = 0, result = [], l = tree.length, rightBasket; for ( let i = 1 ; i < l; i++ ){ if ( tree[i] !== tree[0] ){ rightBasket = i; break ; } } for ( let i = 1 ; i < l; i++ ){ if ( (tree[i] !== tree[leftBasket]) && ( tree[i] == tree[rightBasket] ) ){ rightBasket = i; continue ; } if ( (tree[i] == tree[leftBasket]) && ( tree[i] !== tree[rightBasket] ) ){ leftBasket = i; continue ; } if ( (tree[i] !== tree[leftBasket]) && ( tree[i] !== tree[rightBasket] ) ){ // 结构发生变化时 result.push( start + '$' + ( i - 1) ) for ( let j = i -1 ; j >= 0; j--){ if ( tree[i-1] == tree[j] ){ leftBasket = j; } else { break ; } } start = leftBasket; for ( let j = i; j < l; j++){ if ( tree[j] !== tree[leftBasket]){ rightBasket = j; break ; } } continue ; } } result.push( start + "$" + (l-1) ); let max = -Infinity; result.forEach( (item) => { let temp = item.split( '$' ); if ( temp[1] - temp[0] > max ){ max = temp[1] - temp[0]; } } ) console.log( result ) return max + 1; }; |
老实说这道题拿到手的时候,我花了好长时间理解题意,最终改题目可以抽象为,寻找此数组中连续的并且只有两个元素类型的最长子数组,所以我采用了 三个指针 start,leftBasket,rightBasket ,然后遍历整个数组,当数组的元素既不和leftBasket相等,也不和rightBasket相等时就更新start,leftBasket,rightBasket 的位置,然后在这个时候计算一下当前子序列的长度就好了,我是采用了把结果保存下来的方法,其实也可以不用保存的。
本文作者:子龙_子龙
本文链接:https://www.cnblogs.com/ZiLongZiLong/p/17144913.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通