Merge pull request #1681 from Flow-sandyu/master

Update:增加三道题的解法,修改两处错误
This commit is contained in:
程序员Carl
2022-10-11 10:13:00 +08:00
committed by GitHub
5 changed files with 135 additions and 9 deletions

View File

@ -360,6 +360,75 @@ class Solution {
}
```
```java
/*
* 解法四:时间复杂度 O(n)
* 参考卡哥 c++ 代码的三步骤:先移除多余空格,再将整个字符串反转,最后把单词逐个反转
* 有别于解法一 :没有用 StringBuilder 实现,而是对 String 的 char[] 数组操作来实现以上三个步骤
*/
class Solution {
//用 char[] 来实现 String 的 removeExtraSpacesreverse 操作
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

View File

@ -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

View File

@ -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();

View File

@ -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

View File

@ -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)就可以搞定。**