title: Day38-数据结构与算法-练习题
date: 2021-03-01 15:59:17
author: Liu_zimo
常用的经典数据结构
- 翻转字符串里的单词
- 给定一个字符串,逐个翻转字符串中的每个单词。
- 输入:“the sky is blue”、" hello world! "、“a good example”
- 输出:“blue is sky the”、"world! hello "、“example good a”
- 输入字符串可以在前面或者后面包含多余的空格,但是反转后的字符不能包括。
- 如果两个单词间有多余的空格,将反转后单词间的空格减少到只含一个。

package com.zimo.练习;
public class 翻转字符串 {
public static String reverseWords(String s){
if (s == null) return "";
char[] chars = s.toCharArray();
int len = 0;
int cur = 0;
boolean isSpace = true;
for (int i = 0; i < chars.length; i++) {
if (chars[i] != ' '){
chars[cur++] = chars[i];
isSpace = false;
}else if(isSpace == false){
chars[cur++] = ' ';;
isSpace = true;
}
}
len = isSpace ? cur -1 : cur;
if (len <= 0) return "";
reverse(chars, 0, len);
int prevSpaceIndex = -1;
for (int i = 0; i < len; i++) {
if (chars[i] != ' ') continue;
reverse(chars, prevSpaceIndex + 1, i);
prevSpaceIndex = i;
}
reverse(chars, prevSpaceIndex + 1, len);
return new String(chars, 0, len);
}
private static void reverse(char[] chars, int left, int right){
right--;
while (left < right){
char temp = chars[left];
chars[left] = chars[right];
chars[right] = temp;
left++;
right--;
}
}
public static void main(String[] args) {
System.out.println(reverseWords(" hello world! "));
System.out.println(reverseWords("a good example"));
System.out.println(reverseWords("are you ok"));
}
}
- 无重复字符的最长子串
- 给定一个字符串,请你找出其中不含有重复字符的最长子串的长度
- 输入:“abcabcbb”、“bbbbbbb”、“pwwkew”
- 输出:3、1、3
位置 |
字符 |
以这个字符结尾的最长无重复子串 |
以这个字符结尾的最长无重复子串的长度 |
0 |
p |
p |
1 |
1 |
w |
pw |
2 |
2 |
w |
w |
1 |
3 |
k |
wk |
2 |
4 |
e |
wke |
3 |
5 |
w |
kew |
3 |
package com.zimo.练习;
import java.util.HashMap;
public class 无重复字符的最长子串 {
public static int lengthOfLongestSubstring(String s){
if (s == null) return 0;
char[] chars = s.toCharArray();
if (chars.length == 0) return 0;
HashMap<Character, Integer> prevIndex = new HashMap<>();
prevIndex.put(chars[0], 0);
int li = 0;
int max = 1;
for (int i = 1; i < chars.length; i++) {
Integer prevIdx = prevIndex.getOrDefault(chars[i], -1);
if (li <= prevIdx){
li = prevIdx + 1;
}
prevIndex.put(chars[i], i);
max = Math.max(max, i - li + 1);
}
return max;
}
}
- 礼物的最大价值
- 在一个m*n的棋盘的每一格都放有一个礼物,每个礼物都有一定的价值(价值大于0)。你可以从棋盘的左上角开始拿格子里的礼物,并每次向右或者向下移动一格、直到到达棋盘的右下角。给定一个棋盘及其上面的礼物的价值,请计算你最多能拿到多少价值的礼物?
- dp [row] [col] = max(dp [row] [col - 1], dp[row - 1] [col]) + grid [row] [col]
package com.zimo.练习;
public class 礼物的最大价值 {
public static int maxValue(int[][] grid){
int rows = grid.length;
int cols = grid[0].length;
int[][] dp = new int[rows][cols];
for (int col = 0; col < cols; col++) {
dp[0][col] = col == 0 ? grid[0][0] : dp[0][col - 1] + grid[0][col];
}
for (int row = 1; row < rows; row++) {
dp[row][0] = dp[row - 1][0] + grid[row][0];
}
for (int row = 1; row < rows; row++) {
for (int col = 1; col < cols; col++) {
dp[row][col] = Math.max(dp[row][col - 1], dp[row - 1][col]);
}
}
return dp[rows - 1][cols - 1];
}
public static void main(String[] args) {
int[][] grid = {
{
1, 3, 1, 2}, {
1, 5, 1, 3}, {
4, 2, 1, 4}, {
3, 2, 6, 5}};
System.out.println(maxValue(grid));
}
}