剑指offer 61~66

题目描述

请实现两个函数,分别用来序列化和反序列化二叉树
/*
public class TreeNode {
    int val = 0;
    TreeNode left = null;
    TreeNode right = null;

    public TreeNode(int val) {
        this.val = val;

    }

}
*/
public class Solution {
    public int index = -1;  //节点在序列中的索引

    String Serialize(TreeNode root) {
        StringBuffer strbuf = new StringBuffer();
        if (root == null) {
            strbuf.append("#,");
            return strbuf.toString();
        }
        strbuf.append(root.val+",");
        strbuf.append(Serialize(root.left));
        strbuf.append(Serialize(root.right));
        return strbuf.toString();
    }

    TreeNode Deserialize(String str) {
        index++;
        if (index >= str.length()) return null;
        String stra[] = str.split(",");
        TreeNode root = null;
        if (!stra[index].equals("#")) {
            root = new TreeNode(Integer.parseInt(stra[index]));
            root.left = Deserialize(str);
            root.right = Deserialize(str);
        }
        return root;
    }
}

题目描述

给定一棵二叉搜索树,请找出其中的第k小的结点。例如, (5,3,7,2,4,6,8) 中,按结点数值大小顺序第三小结点的值为4。
/*
public class TreeNode {
    int val = 0;
    TreeNode left = null;
    TreeNode right = null;

    public TreeNode(int val) {
        this.val = val;

    }

}
*/
import java.util.ArrayList;
public class Solution {
     int index = 0;

     TreeNode KthNode(TreeNode pRoot, int k) {
        if (pRoot != null) {
            TreeNode node = KthNode(pRoot.left, k);
            if (node != null) return node;
            index++;
            if (index == k) return pRoot;
            node = KthNode(pRoot.right, k);
            if (node != null) return node;
        }
        return null;
    }

}

题目描述

如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值。我们使用Insert()方法读取数据流,使用GetMedian()方法获取当前读取数据的中位数。
import java.util.*;
public class Solution {

    PriorityQueue<Integer> min = new PriorityQueue<>();
    PriorityQueue<Integer> max = new PriorityQueue<>(15, new Comparator<Integer>() {
        @Override
        public int compare(Integer o1, Integer o2) {
            return o2 - o1;
        }
    });
    int count = 0;

    public void Insert(Integer num) {
        count++;
        if (count % 2 == 1) {
            max.offer(num);
            min.offer(max.poll());
        } else {
            min.offer(num);
            max.offer(min.poll());
        }
    }
    public Double GetMedian() {
        if (count % 2 == 0) return (min.peek() + max.peek()) / 2.0;
        else return (double) min.peek();
    }


}

题目描述

给定一个数组和滑动窗口的大小,找出所有滑动窗口里数值的最大值。例如,如果输入数组{2,3,4,2,6,2,5,1}及滑动窗口的大小3,那么一共存在6个滑动窗口,他们的最大值分别为{4,4,6,6,6,5}; 针对数组{2,3,4,2,6,2,5,1}的滑动窗口有以下6个: {[2,3,4],2,6,2,5,1}, {2,[3,4,2],6,2,5,1}, {2,3,[4,2,6],2,5,1}, {2,3,4,[2,6,2],5,1}, {2,3,4,2,[6,2,5],1}, {2,3,4,2,6,[2,5,1]}。
import java.util.ArrayList;
public class Solution {
    public ArrayList<Integer> maxInWindows(int[] num, int size) {
        int max = Integer.MIN_VALUE;
        ArrayList<Integer> array = new ArrayList<>();
        if (size == 0) return array;
        for (int i = 0; i <= num.length - size; i++) {
            for (int j = i; j < i + size; j++) {
                while (num[j] > max) {
                    max = num[j];
                }
            }
            array.add(max);
            max = Integer.MIN_VALUE;
        }
        return array;
    }
}

题目描述

请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向左,向右,向上,向下移动一个格子。如果一条路径经过了矩阵中的某一个格子,则之后不能再次进入这个格子。 例如 a b c e s f c s a d e e 这样的3 X 4 矩阵中包含一条字符串"bcced"的路径,但是矩阵中不包含"abcb"路径,因为字符串的第一个字符b占据了矩阵中的第一行第二个格子之后,路径不能再次进入该格子。
public class Solution {

 public boolean hasPath(char[] matrix, int rows, int cols, char[] str) {
        if (matrix == null || matrix.length != rows * cols || str == null || str.length == 0 || str.length > matrix.length)
            return false;
        boolean visited[] = new boolean[matrix.length];
        for (int j = 0; j < rows; j++) {
            for (int i = 0; i < cols; i++) {
                if (dfs(matrix, rows, cols, str, i, j, 0, visited)) return true;
            }
        }
        return false;
    }

    private boolean dfs(char[] matrix, int rows, int cols, char[] str, int i, int j, int k, boolean[] visited) {
        if (i < 0 || i >= cols || j < 0 || j >= rows || visited[i + j * cols] || matrix[i + j * cols] != str[k])
            return false;
        if (k == str.length - 1) return true;
        visited[i + j * cols] = true;
        if (dfs(matrix, rows, cols, str, i, j - 1, k + 1, visited)
                || dfs(matrix, rows, cols, str, i + 1, j, k + 1, visited)
                || dfs(matrix, rows, cols, str, i, j + 1, k + 1, visited)
                || dfs(matrix, rows, cols, str, i - 1, j, k + 1, visited))
            return true;
        visited[i + j * cols] = false;
        return false;
    }
}

题目描述

地上有一个m行和n列的方格。一个机器人从坐标0,0的格子开始移动,每一次只能向左,右,上,下四个方向移动一格,但是不能进入行坐标和列坐标的数位之和大于k的格子。 例如,当k为18时,机器人能够进入方格(35,37),因为3+5+3+7 = 18。但是,它不能进入方格(35,38),因为3+5+3+8 = 19。请问该机器人能够达到多少个格子?
public class Solution {
    public int movingCount(int threshold, int rows, int cols) {
        boolean visited[] = new boolean[rows * cols];
        int count = movingCountCore(threshold, rows, cols, 0, 0, visited);
        return count;
    }

    int movingCountCore(int threshold, int rows, int cols, int row, int col, boolean[] visited) {
        int count = 0;
        if (check(threshold, rows, cols, row, col, visited)) {
            visited[row * cols + col] = true;
            count = 1 + movingCountCore(threshold, rows, cols, row - 1, col, visited) +
                    movingCountCore(threshold, rows, cols, row + 1, col, visited) +
                    movingCountCore(threshold, rows, cols, row, col - 1, visited) +
                    movingCountCore(threshold, rows, cols, row, col + 1, visited);
        }
        return count;
    }

     boolean check(int threshold, int rows, int cols, int row, int col, boolean[] visited) {
        if (row < 0 || row >= rows || col < 0 || col >= cols || (getDigit(row) + getDigit(col)) > threshold || visited[row * cols + col])
            return false;
        return true;
    }

     int getDigit(int num) {
        int sum = 0;
        while (num > 0) {
            sum += num % 10;
            num /= 10;
        }
        return sum;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值