剑指 Offer 58 - I. 翻转单词顺序(151. 反转字符串中的单词)
题目:
思路:
【1】感觉考察的是对函数的内置逻辑的理解和重点思考如何使用java写出空间复杂度为O(n)的算法。
代码展示:
//时间8 ms击败31.44% //内存41.6 MB击败29.24% //利用函数的写法,巨简洁 class Solution { public String reverseWords(String s) { // 除去开头和末尾的空白字符 s = s.trim(); // 正则匹配连续的空白字符作为分隔符分割 List<String> wordList = Arrays.asList(s.split("\\s+")); Collections.reverse(wordList); return String.join(" ", wordList); } }
按空格分割的方式:
//时间7 ms击败16.96% //内存41.2 MB击败77.36% class Solution { public String reverseWords(String s) { if (s == "" || s == null) return s; String[] arr = s.split(" "); StringBuffer res = new StringBuffer(); for (int i = arr.length-1; i >= 0; i--) { System.out.println(arr[i]); if (arr[i] == " " || arr[i] == "") continue; res.append(' ').append(arr[i]); } return res.length() > 0 ? res.substring(1,res.length()).toString() : ""; } }
将字符串转成字符数组的方式进行处理:
//时间5 ms击败34.58% //内存41.1 MB击败93.76% class Solution { public String reverseWords(String s) { s = s.trim(); if (s == "" && s == null) return s; char[] arr = s.toCharArray(); StringBuffer charArr = new StringBuffer(); StringBuffer res = new StringBuffer(); for (int i = arr.length-1; i >= 0; i--) { if (arr[i] == ' ' && charArr.length() != 0) { res.append(charArr).append(' '); charArr = new StringBuffer(); } if (arr[i] == ' ') continue; charArr.insert(0,arr[i]); } if (charArr.length() != 0) res.append(charArr); return res.toString(); } } //如果不给用trim()函数方法 //时间5 ms击败34.58% //内存41.2 MB击败83.87% class Solution { public String reverseWords(String s) { //先去掉两边的空格 int left = 0,right = s.length()-1; while (left<right && (s.charAt(left) == ' ' || s.charAt(right)== ' ')){ if (s.charAt(left) == ' ') left++; if (s.charAt(right) == ' ') right--; } s = s.substring(left,right+1); if (s == "" || s == null) return s; //将两边处理空格后的字符串进行翻转处理 char[] arr = s.toCharArray(); StringBuffer charArr = new StringBuffer(); StringBuffer res = new StringBuffer(); for (int i = arr.length-1; i >= 0; i--) { if (arr[i] == ' ' && charArr.length() != 0) { res.append(' ').append(charArr); charArr = new StringBuffer(); } if (arr[i] == ' ') continue; charArr.insert(0,arr[i]); } if (charArr.length() != 0) res.append(' ').append(charArr); //这里写的很骚,但是因为例题s = "";竟然能跳过我前面的判断就很迷,本地跳不过,所以特殊处理了 return res.length()>0 ? res.substring(1,res.length()).toString() : ""; } }
//时间3 ms击败88.95% //内存40.4 MB击败93.7% class Solution { public String reverseWords(String s) { char[] ch = s.toCharArray(); int slow = 0; int fast = 0; //双指针清除多余空格 for(int i=0;i<ch.length;i++){ if(ch[fast] != ' '){//正常非空格 ch[slow] = ch[fast]; slow++; fast++; }else if(slow-1>=0 && ch[slow-1]!=' '){//是空格,但是前面没有空格,需要添加 ch[slow] = ch[fast]; slow++; fast++; }else{//是空格,前面已经有空格,需要添加 fast++; } } if(ch[ch.length-1]==' ')slow--; //全部反转 reverse(ch, 0, slow-1); //单词再反转 for(int i=0;i<slow;){ for(int j=i;j<slow;j++){//注意点:j=i,这样当单词为1个字符的时候才能命中 if(ch[j]==' '){ reverse(ch, i, j-1); i=j+1; break; }else if(j == slow -1){ reverse(ch, i, j); i=j+1; break; } } } return new String(ch).substring(0,slow); } private void reverse(char[] ch, int start, int end){ while(start<end){ char temp = ch[start]; ch[start] = ch[end]; ch[end] = temp; start++; end--; } } }