【leetcode剑指offer刷题笔记】数据结构部分03-07

03. 数组中重复的数字

思路

一种hash思想,感觉有点类似于用基数排序的方法排序全国人年龄,注意题目限制了数字的大小,所以hash数组的大小也好确认了。

代码

class Solution {
    public int findRepeatNumber(int[] nums) {
        //一种hash思想
        int[] arr = new int[nums.length];
        for(int i = 0; i < nums.length; i++){
            int num = nums[i];
            arr[num]++;
            if (arr[num] > 1)
                return num;
        }
        return 0;
    }
}

结果与分析

2ms

04. 二维数组中的查找

思路

这种有序的肯定从这个序上去找规律,显然从右上角开始找,target小则往左走,大了则往下走。

代码

class Solution {
    public boolean findNumberIn2DArray(int[][] matrix, int target) {
        if(matrix == null||matrix.length == 0)
            return false;
        int wide = matrix[0].length;
        int high = matrix.length;
        int i =0, j = wide - 1 ;
        while(i<high && j>=0){
            if(matrix[i][j] == target){
                return true;
            }else if(matrix[i][j]>target){
                j--;
            }else{
                i++;
            }
        }
        return false;
    }
}

结果与分析

0ms,有个坑就是有个输入是[]为空

05. 替换空格

思路

刚开始想到的方法很笨,将string转化为char数组,把数组元素依次放入队列,如果是空格就放入%20,然后将队列出队成string。2ms只超过了11%的人。
草率地看了看评论区有几种思路:1.使用StringBuilder 2.使用replaceAll库函数

代码

class Solution {
    public String replaceSpace(String s) {
       //方法二,使用StringBuilder
       StringBuilder sb = new StringBuilder();
       for (int i = 0; i < s.length();i++){
           char c = s.charAt(i);
           if(c == ' '){
               sb.append("%20");
           }else{
               sb.append(c);
           }
       }
       return sb.toString();
    }   
       
}

结果与分析

0ms,如果要修改字符串,使用StringBuilder还是很方便的。

06. 从尾到头打印链表

思路

一开始就能想到利用栈还是比较方便的,另外遍历链表知道长度可以直接读链表从数组尾插入

代码

class Solution {
    public int[] reversePrint(ListNode head) {
        //把链表放入栈
        Stack<Integer> stack = new Stack<Integer>();
        ListNode p = head;
        int length = 0;
        while(p!=null){
            stack.push(p.val);
            p = p.next;
            length++;
        }
        int[] arr = new int[length];
        for(int i = 0; !stack.empty(); i++){
            arr[i] = stack.pop();
        }
        return arr;
    }

}

结果与分析

2ms 20%。如果用第二种方法则100%。

07. 重建二叉树

思路

先序+中序确定二叉树算法。
借用评论区的讲解:

  • 前序遍历列表:第一个元素永远是 【根节点 (root)】
  • 中序遍历列表:根节点(root)【左边】的所有元素都在根节点的【左分支】,【右边】的所有元素都在根节点的【右分支】

算法思路:

  1. 通过【前序遍历列表】确定【根节点 (root)】
  2. 将【中序遍历列表】的节点分割成【左分支节点】和【右分支节点】
  3. 递归寻找【左分支节点】中的【根节点 (left child)】和 【右分支节点】中的【根节点 (right child)】

代码

class Solution {
    public TreeNode buildTree(int[] preorder, int[] inorder) {
        int n = preorder.length;
        if(n == 0)
            return null;
        int rootVal = preorder[0];
        int rootIndex = 0;
        for(int i = 0; i < n;i++){
            if(inorder[i] == rootVal){
                rootIndex = i;
                break;
            }
        }
        TreeNode root = new TreeNode(rootVal);
        //左子树中只可能有rootIndex个结点
        //注意copyOfRange函数左闭右开
        root.left = buildTree(Arrays.copyOfRange(preorder,1,rootIndex+1),Arrays.copyOfRange(inorder,0,rootIndex));
        root.right = buildTree(Arrays.copyOfRange(preorder,rootIndex+1,n),Arrays.copyOfRange(inorder,rootIndex+1,n));

        return root;

    }
}

结果与分析

8 ms 13.14%。但是这个递归的写法和思路很清晰。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值