mirror of
https://github.com/youngyangyang04/leetcode-master.git
synced 2025-07-08 16:54:50 +08:00
Merge pull request #1681 from Flow-sandyu/master
Update:增加三道题的解法,修改两处错误
This commit is contained in:
@ -360,6 +360,75 @@ class Solution {
|
||||
}
|
||||
```
|
||||
|
||||
```java
|
||||
/*
|
||||
* 解法四:时间复杂度 O(n)
|
||||
* 参考卡哥 c++ 代码的三步骤:先移除多余空格,再将整个字符串反转,最后把单词逐个反转
|
||||
* 有别于解法一 :没有用 StringBuilder 实现,而是对 String 的 char[] 数组操作来实现以上三个步骤
|
||||
*/
|
||||
class Solution {
|
||||
//用 char[] 来实现 String 的 removeExtraSpaces,reverse 操作
|
||||
public String reverseWords(String s) {
|
||||
char[] chars = s.toCharArray();
|
||||
//1.去除首尾以及中间多余空格
|
||||
chars = removeExtraSpaces(chars);
|
||||
//2.整个字符串反转
|
||||
reverse(chars, 0, chars.length - 1);
|
||||
//3.单词反转
|
||||
reverseEachWord(chars);
|
||||
return new String(chars);
|
||||
}
|
||||
|
||||
//1.用 快慢指针 去除首尾以及中间多余空格,可参考数组元素移除的题解
|
||||
public char[] removeExtraSpaces(char[] chars) {
|
||||
int slow = 0;
|
||||
for (int fast = 0; fast < chars.length; fast++) {
|
||||
//先用 fast 移除所有空格
|
||||
if (chars[fast] != ' ') {
|
||||
//在用 slow 加空格。 除第一个单词外,单词末尾要加空格
|
||||
if (slow != 0)
|
||||
chars[slow++] = ' ';
|
||||
//fast 遇到空格或遍历到字符串末尾,就证明遍历完一个单词了
|
||||
while (fast < chars.length && chars[fast] != ' ')
|
||||
chars[slow++] = chars[fast++];
|
||||
}
|
||||
}
|
||||
//相当于 c++ 里的 resize()
|
||||
char[] newChars = new char[slow];
|
||||
System.arraycopy(chars, 0, newChars, 0, slow);
|
||||
return newChars;
|
||||
}
|
||||
|
||||
//双指针实现指定范围内字符串反转,可参考字符串反转题解
|
||||
public void reverse(char[] chars, int left, int right) {
|
||||
if (right >= chars.length) {
|
||||
System.out.println("set a wrong right");
|
||||
return;
|
||||
}
|
||||
while (left < right) {
|
||||
chars[left] ^= chars[right];
|
||||
chars[right] ^= chars[left];
|
||||
chars[left] ^= chars[right];
|
||||
left++;
|
||||
right--;
|
||||
}
|
||||
}
|
||||
|
||||
//3.单词反转
|
||||
public void reverseEachWord(char[] chars) {
|
||||
int start = 0;
|
||||
//end <= s.length() 这里的 = ,是为了让 end 永远指向单词末尾后一个位置,这样 reverse 的实参更好设置
|
||||
for (int end = 0; end <= chars.length; end++) {
|
||||
// end 每次到单词末尾后的空格或串尾,开始反转单词
|
||||
if (end == chars.length || chars[end] == ' ') {
|
||||
reverse(chars, start, end - 1);
|
||||
start = end + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
python:
|
||||
|
||||
```Python
|
||||
|
@ -292,6 +292,40 @@ class MyStack {
|
||||
}
|
||||
```
|
||||
|
||||
优化,使用一个 Queue 实现
|
||||
```java
|
||||
class MyStack {
|
||||
|
||||
Queue<Integer> queue;
|
||||
|
||||
public MyStack() {
|
||||
queue = new LinkedList<>();
|
||||
}
|
||||
|
||||
//每 offer 一个数(A)进来,都重新排列,把这个数(A)放到队列的队首
|
||||
public void push(int x) {
|
||||
queue.offer(x);
|
||||
int size = queue.size();
|
||||
//移动除了 A 的其它数
|
||||
while (size-- > 1)
|
||||
queue.offer(queue.poll());
|
||||
}
|
||||
|
||||
public int pop() {
|
||||
return queue.poll();
|
||||
}
|
||||
|
||||
public int top() {
|
||||
return queue.peek();
|
||||
}
|
||||
|
||||
public boolean empty() {
|
||||
return queue.isEmpty();
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
Python:
|
||||
|
||||
```python
|
||||
|
@ -156,20 +156,20 @@ char* replaceSpace(char* s){
|
||||
Java:
|
||||
```Java
|
||||
//使用一个新的对象,复制 str,复制的过程对其判断,是空格则替换,否则直接复制,类似于数组复制
|
||||
public static String replaceSpace(StringBuffer str) {
|
||||
if (str == null) {
|
||||
public static String replaceSpace(String s) {
|
||||
if (s == null) {
|
||||
return null;
|
||||
}
|
||||
//选用 StringBuilder 单线程使用,比较快,选不选都行
|
||||
//选用 StringBuilder 单线程使用,比较快,选不选都行
|
||||
StringBuilder sb = new StringBuilder();
|
||||
//使用 sb 逐个复制 str ,碰到空格则替换,否则直接复制
|
||||
for (int i = 0; i < str.length(); i++) {
|
||||
//str.charAt(i) 为 char 类型,为了比较需要将其转为和 " " 相同的字符串类型
|
||||
//if (" ".equals(String.valueOf(str.charAt(i)))){
|
||||
//使用 sb 逐个复制 s ,碰到空格则替换,否则直接复制
|
||||
for (int i = 0; i < s.length(); i++) {
|
||||
//s.charAt(i) 为 char 类型,为了比较需要将其转为和 " " 相同的字符串类型
|
||||
//if (" ".equals(String.valueOf(s.charAt(i)))){}
|
||||
if (s.charAt(i) == ' ') {
|
||||
sb.append("%20");
|
||||
} else {
|
||||
sb.append(str.charAt(i));
|
||||
sb.append(s.charAt(i));
|
||||
}
|
||||
}
|
||||
return sb.toString();
|
||||
|
@ -115,6 +115,29 @@ class Solution {
|
||||
}
|
||||
```
|
||||
|
||||
```java
|
||||
//解法二:空间复杂度:O(1)。用原始数组来进行反转操作
|
||||
//思路为:先整个字符串反转,再反转前面的,最后反转后面 n 个
|
||||
class Solution {
|
||||
public String reverseLeftWords(String s, int n) {
|
||||
char[] chars = s.toCharArray();
|
||||
reverse(chars, 0, chars.length - 1);
|
||||
reverse(chars, 0, chars.length - 1 - n);
|
||||
reverse(chars, chars.length - n, chars.length - 1);
|
||||
return new String(chars);
|
||||
}
|
||||
|
||||
public void reverse(char[] chars, int left, int right) {
|
||||
while (left < right) {
|
||||
chars[left] ^= chars[right];
|
||||
chars[right] ^= chars[left];
|
||||
chars[left] ^= chars[right];
|
||||
left++;
|
||||
right--;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
python:
|
||||
|
||||
```python
|
||||
|
@ -42,7 +42,7 @@ for (int i = 0; i < array.size(); i++) {
|
||||
|
||||
**其实很多数组(字符串)填充类的问题,都可以先预先给数组扩容带填充后的大小,然后在从后向前进行操作。**
|
||||
|
||||
那么在[字符串:花式反转还不够!](https://programmercarl.com/0151.翻转字符串里的单词.html)中,我们使用双指针法,用O(n)的时间复杂度完成字符串删除类的操作,因为题目要产出冗余空格。
|
||||
那么在[字符串:花式反转还不够!](https://programmercarl.com/0151.翻转字符串里的单词.html)中,我们使用双指针法,用O(n)的时间复杂度完成字符串删除类的操作,因为题目要删除冗余空格。
|
||||
|
||||
**在删除冗余空格的过程中,如果不注意代码效率,很容易写成了O(n^2)的时间复杂度。其实使用双指针法O(n)就可以搞定。**
|
||||
|
||||
|
Reference in New Issue
Block a user