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) ) ;
}
}