while 循环的写法,我觉得自己一直写的举步维艰。拿一些简单的例子,我们刻意强化下这块吧。

151. 颠倒字符串中的单词

操作思路:
遍历字符串,遇到空字符串,就把之前积累的字符成word,存入响应数据结构里,然后周而复始

  1. var reverseWords = function(s) {
  2. s = s.trim();
  3. s += ' '; // 构造更规律的结构
  4. let n = s.length;
  5. let queue = [];
  6. let pre = '';
  7. let i = 0;
  8. while (i < n) { // 因为单词之间可能有多个连续空格,所以使用 for 循环会比较不好理解
  9. if (s[i] !== ' ') {
  10. pre += s[i];
  11. } else {
  12. if (pre) { // pre 的判断是题眼!!!
  13. queue.unshift(pre);
  14. pre = '';
  15. }
  16. }
  17. i++;
  18. }
  19. return queue.join(' ');
  20. };

58. 最后一个单词的长度

  1. var lengthOfLastWord = function(s) {
  2. s = ' ' + s + ' ';
  3. let ans = [];
  4. let pre = '';
  5. for (let char of s) {
  6. if (char === ' ') {
  7. if (pre) {
  8. ans.push(pre);
  9. pre = '';
  10. }
  11. continue;
  12. } else {
  13. pre = pre + char;
  14. }
  15. }
  16. return ans[ans.length - 1].length;
  17. };

8. 字符串转换整数 (atoi)

累加整数成和

  1. var myAtoi = function(s) {
  2. s = s.trim();
  3. let fristLetter = s[0];
  4. let sign = 1; // 默认正号
  5. if (fristLetter === '-') {
  6. sign = -1;
  7. s = s.slice(1);
  8. } else if (fristLetter === '+') {
  9. s = s.slice(1);
  10. }
  11. let limit = Math.pow(2,31);
  12. let n = s.length;
  13. let num = 0;
  14. let i = 0;
  15. while (i < n) {
  16. let cur = s[i];
  17. if (cur < '0' || cur > '9') { // 不是数字
  18. break;
  19. }
  20. num = num * 10 + Number(cur) * sign; //
  21. // if (num === Infinity) { // 不符合题目要求
  22. // return Infinity;
  23. // }
  24. if (num >= limit - 1) { // 题目要求整数数超过 32 位有符号整数范围 [−231, 231 − 1]
  25. return limit - 1;
  26. } else if (num < -limit) {
  27. return -limit
  28. }
  29. i++;
  30. }
  31. return num;
  32. };

剑指 Offer 05. 替换空格

从尾部开始替换。

  1. var replaceSpace = function(s) {
  2. let n = s.length;
  3. let i = n - 1;
  4. while (i >= 0) {
  5. if (s[i] === ' ') {
  6. s = s.slice(0, i) + '%20' + s.slice(i + 1)
  7. }
  8. i--;
  9. }
  10. return s;
  11. };

二、while 和 for 结合的写法:

1.树的层序遍历

2.不断过滤一个集合,直到集合为空

与树的层序遍历写法是一样的。

127. 单词接龙

  1. var ladderLength = function(beginWord, endWord, wordList) {
  2. if (wordList.length === 0 || !wordList.includes(endWord)) {
  3. return 0;
  4. }
  5. const wordDict = new Set(wordList); // set 查找速度比 array 快的多
  6. const queue = [beginWord]; // 1. 全局 queue 声明
  7. while (queue.length > 0) {
  8. let size = queue.length;
  9. for (let i = 0; i < size; i++) {
  10. let curWord = queue.shift();
  11. const result = didMatch(curWord, endWord);
  12. if (result) {
  13. return true;
  14. }
  15. }
  16. }
  17. function didMatch(curWord, targetWord) { // curWord 和 targetWord 长度相同
  18. for (let i = 0; i < curWord.length; i++) { // 每个字符都要替换比较
  19. for (let c = 97; c < 123; c++) {
  20. let changedChar = String.fromCharCode(c);
  21. let changedWord = curWord.slice(0, i) + changedChar + curWord.slice(i + 1);
  22. if (changedWord === targetWord) {
  23. return true;
  24. }
  25. if (wordDict.has(changedWord)) {
  26. queue.push(changedWord); // 1. 全局 queue 加入
  27. wordDict.delete(changedWord); // 匹配过的就删了
  28. }
  29. }
  30. }
  31. return false;
  32. }
  33. return true;
  34. };