Day38-数据结构与算法-练习题


title: Day38-数据结构与算法-练习题
date: 2021-03-01 15:59:17
author: Liu_zimo


常用的经典数据结构

  1. 翻转字符串里的单词
    • 给定一个字符串,逐个翻转字符串中的每个单词。
    • 输入:“the sky is blue”、" hello world! "、“a good example”
    • 输出:“blue is sky the”、"world! hello "、“example good a”
      • 输入字符串可以在前面或者后面包含多余的空格,但是反转后的字符不能包括。
      • 如果两个单词间有多余的空格,将反转后单词间的空格减少到只含一个。

1

package com.zimo.练习;

/**
 * 翻转字符串 - leetcode 151
 *
 * @author Liu_zimo
 * @version v0.1 by 2021/3/1 16:53
 */
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; // 前面一个字符是否为空格字符,初始化为true防止开头有空格

        for (int i = 0; i < chars.length; i++) {
    
    
            if (chars[i] != ' '){
    
               // chars[i]是非空格字符
                chars[cur++] = chars[i];
                isSpace = false;
            }else if(isSpace == false){
    
         //chars[i]是空格字符,chars[i - 1]是非空格字符
                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);
    }
    // 范围:[left, right)
    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"));
    }
}
  1. 无重复字符的最长子串
    • 给定一个字符串,请你找出其中不含有重复字符的最长子串的长度
    • 输入:“abcabcbb”、“bbbbbbb”、“pwwkew”
    • 输出:3、1、3
0 1 2 3 4 5
p w w k e w
位置 字符 以这个字符结尾的最长无重复子串 以这个字符结尾的最长无重复子串的长度
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;

/**
 * 无重复字符的最长子串 - leetcode 151
 *
 * @author Liu_zimo
 * @version v0.1 by 2021/3/1 17:52
 */
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; // char[i-1]最长不重复子串的开始索引(最左索引)
        int max = 1;
        for (int i = 1; i < chars.length; i++) {
    
    
            Integer prevIdx = prevIndex.getOrDefault(chars[i], -1);    // chars[i]上一次出现的位置

            if (li <= prevIdx){
    
    
                li = prevIdx + 1;
            }

            // 存储,更新当前字符出现的位置
            prevIndex.put(chars[i], i);
            // 求出无重复字符的最长子串
            max = Math.max(max, i - li + 1);
        }
        return max;
    }
}
  1. 礼物的最大价值
    • 在一个m*n的棋盘的每一格都放有一个礼物,每个礼物都有一定的价值(价值大于0)。你可以从棋盘的左上角开始拿格子里的礼物,并每次向右或者向下移动一格、直到到达棋盘的右下角。给定一个棋盘及其上面的礼物的价值,请计算你最多能拿到多少价值的礼物?
    • dp [row] [col] = max(dp [row] [col - 1], dp[row - 1] [col]) + grid [row] [col]
package com.zimo.练习;

/**
 * 无重复字符的最长子串 - leetcode 47
 *
 * @author Liu_zimo
 * @version v0.1 by 2021/3/2 14:06
 */
public class 礼物的最大价值 {
    
    
    public static int maxValue(int[][] grid){
    
    
        int rows = grid.length;
        int cols = grid[0].length;

        int[][] dp = new int[rows][cols];

        // 第0行
        for (int col = 0; col < cols; col++) {
    
    
            dp[0][col] = col == 0 ? grid[0][0] : dp[0][col - 1] + grid[0][col];
        }
        // 第0列
        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));
    }
}

猜你喜欢

转载自blog.csdn.net/qq_38205875/article/details/114284776