剑指 Offer(3~7)


一、03 数组中重复的数字

1.算法描述

在一个长度为 n 的数组 nums 里的所有数字都在 0 ~ n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。

2.算法题解

  • 看到题首先想到的是遍历数组,将数字添加到 set 中,如果添加失败则数字重复。

  • 另一种解法是数组重组:如果在没有重复数字的情况下,正常排序后,数字 i 应该在下标为 i 的位置。将数组进行扫描重组,如果下标为 i 的数字不为 i 的话(假设为 j),那么我们将下标 i 和 j 的数字进行交换,在交换过程中如果有重复数字则直接返回。

class Solution {
    public int findRepeatNumber(int[] nums) {
        for (int i = 0; i < nums.length; i++) {
            while (nums[i] != i) {
            	// 如果下标为 nums[i] 的位置已经有数字则代表有重复 
                if (nums[i] == nums[nums[i]]) {
                    return nums[i];
                }
                int tmp = nums[i];
                nums[i] = nums[tmp];
                nums[tmp] = tmp;
            }
        }
        return -1;
    }
}

二、04 二维数组中的查找

1.算法描述

在一个 n * m 的二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个高效的函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。

2.算法题解

利用二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序的特点,可以得出一行中值最大的下标是行尾,一列中值最大的下标是列尾,由此可以从数组的右上角开始查找(即下标为 0, matrix[0].length-1),有一下三种情况:

  • 如果当前元素大于目标值则向左移动一列,因为当前元素下面的所有元素一定大于当前元素也大于目标值,所有向下查找不能找到目标值,只能想左查找。
  • 如果当前元素小于目标值则向下移动一行,因为当前元素左面的所有元素一下小于当前元素也小于目标值,所以向左查找不能找到目标值,只能向下查找。
  • 如果当前元素等于目标值则直接返回。
class Solution {
    public boolean findNumberIn2DArray(int[][] matrix, int target) {
        if (matrix == null || matrix.length == 0) {
            return false;
        }
        int rows = matrix.length;
        int columns = matrix[0].length;
        int row = 0, column = columns - 1;
        while (row < rows && column >= 0) {
            int num = matrix[row][column];
            if (num > target) {
                column--;
            } else if (num < target) {
                row++;
            } else {
                return true;
            }
        }
        return false;
    }
}

三、05 替换空格

1.算法描述

请实现一个函数,把字符串 s 中的每个空格替换成"%20"。

2.算法题解

大佬请使用 String.replaceAll()

class Solution {
    public String replaceSpace(String s) {
        StringBuilder builder = new StringBuilder();
        char[] chars = s.toCharArray();
        for (char aChar : chars) {
            if (aChar == ' ') {
                builder.append("%20");
            } else {
                builder.append(aChar);
            }
        }
        return builder.toString();
    }
}

四、06 从尾到头打印链表

1.算法描述

输入一个链表的头节点,从尾到头反过来返回每个节点的值(用数组返回)。

2.算法题解

可以使用栈来完成倒序,使用栈的先入后出。

class Solution {
    public int[] reversePrint(ListNode head) {
        Deque<Integer> stack = new LinkedList<>();
        while (head != null) {
            stack.push(head.val);
            head = head.next;
        }
        int index = 0;
        int[] result = new int[stack.size()];
        while (!stack.isEmpty()) {
            result[index++] = stack.pop();
        }
        return result;
    }
}

五、07 重建二叉树

1.算法描述

输入某二叉树的前序遍历和中序遍历的结果,请重建该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。

2.算法题解

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值