剑指offer Java 3-5

3.数组中重复的数字

题目一描述

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

解题思路

(这一题牛客没有,格式就随便写的)

一、由题干,长度为n,数字都在0到n-1范围内可知,将数组数字和序号对应,即可快速查找到重复数字(牛客)

public class Main {
    /**
     *
     * 首先是将数字和下标对应,就可以快速查找是否存在重复值
     *
     * */
    public boolean duplicate(int[] nums, int length, int[] duplication) {
        if (nums == null || length <= 0)  //边界值判断:判断数组是否为空,长度是否小于0
            return false;
        for (int i = 0; i < length; i++) {
            while (nums[i] != i) {  // 如果当前的值和序号不同,则执行,否则该数在合适的位置,遍历下一个
                if (nums[i] == nums[nums[i]]) {  // 如果该数和该数序号下的值相同,就返回该值
                    duplication[0] = nums[i];
                    return true;
                }
                swap(nums, i, nums[i]);  // 否则,将该数字放到他所该在的位置
            }
        }
        return false;
    }

    private void swap(int[] nums, int i, int j) {
        int t = nums[i];
        nums[i] = nums[j];
        nums[j] = t;
    }
}

二、先排序,再找重复值(数字和后一位相同)(剑指)

三、哈希表(剑指)(这个方法写一遍加深哈希表记忆)其实第一个思路也是哈希表思路。

 

题目二描述

在一个长度为 n+1 的数组里的所有数字都在 1 到 n 的范围内。数组中一定有至少一个重复数字,但不知道有几个数字是重复的,也不知道每个数字重复几次。请找出数组中任意一个重复的数字。

解题思路

一、同题目一,使用新数组复制一份之前的数组使用

二、折半查找法,统计数字数目。根据题意一定至少有一个数字重复,折半统计某个区间不断逼近,即可找到这个数(写一遍加深记忆),值得注意的是,该方法有可能无法找到所有的重复数字。

public class Main(){
    public boolean duplicate3(int[] nums, int length, int[] duplication){
        if(nums == null || length <= 0)  //length = n + 1
            return false;
        int start = 1;
        int end = length - 1; // n
        while(end != start){
            int middle = (end+start)/2;
            int c = count(start,middle,nums,length);
            if(c>middle-start+1)
                end = middle;
            else
                start = middle+1;
            if(start == end){
                duplication[0]=start;
                return true;
            }

        }
        return false;
    }
    private int count(int start, int end, int[] nums, int length){
        int c = 0;
        for(int i=0; i<length; i++){
            if(nums[i]>=start && nums[i]<=end)
                c++;
        }
        return c;
    }

}

 

4.二维数组中的查找

题目描述

给定一个二维数组,其每一行从左到右递增排序,从上到下也是递增排序。给定一个数,判断这个数是否在该二维数组中。

解题思路

一开始我的想法是这样的想的太简单了……

一、先横向查找,找到大于该数的列,再纵向查找前一列,直到该数。如果上一个等于下一个,或者上一个和下一个都不等于该数,则返回false,找到值则返回true。查找的方法可以采用(自己)(×)

二、该数组有个特性,就是某个值,小于他的数在他左边,大于他的数在他下面(也可以说大于他的数在他右边,小于他的数在他上边),所以从左下角或者右上角开始查找。从右上角开始,和默认值比较,如果默认值小,则往左走,如果大则往下走,直到左下角即可。(剑指,牛客)

public class Solution {
    public boolean Find(int target, int [][] array) {
        int rowsline = array.length;
        int columnline = array[0].length;
        int i=0,j=columnline-1;
        while (i<=rowsline-1 && j>=0){
            if(array[i][j]==target)
                return true;
            else if(array[i][j]>target)
                j = j-1;
            else
                i = i+1;
        }
        return false;
    }

    public static void main(String args[]){
        int[][] array = {{1,5,9,13},{2,6,10,14},{3,7,11,15},{4,8,12,16}};
        int target = 10;
        Solution s = new Solution();
        System.out.println(s.Find(target, array));
    }
}

 

 

5.替换空格

题目描述

将一个字符串中的空格替换成 "%20"

解题思路

牛客里面使用StringBuffer来存储给定字符串,首先要明确几个StringBuffer的操作

// StringBuffer创建实例
StringBuffer str = new StringBuffer("abc");

// 取StringBuffer的长度
int l = str.length();

// 取StringBuffer中对应的元素
char c =str.CharAt(0);

// 向StringBuffer中追加String或者char
str.append("def");
str.append('g');

// 修改StringBuffer的值
str.setCharAt(1, c);

使用StringBuffer之后,这道题可以采用指针的办法,首先根据空格的数量在字符串后追加2倍的空字符串,P1指向原本的最后一个位置,P2指向新StringBuffer的最后一位,然后再从后往前遍历,遍历不是空字符串,从P1赋值到P2,如果为空,倒叙添加"0""2""%"三个字符。

public class Solution {
    public String replaceSpace(StringBuffer str) {
        if (str == null)
            return "false";
        int P1 = str.length() - 1;
        for (int i=0;i<=P1;i++){
            if (str.charAt(i) == ' '){
                str.append("  ");
            }
        }
        int P2 = str.length() - 1;
        for (int i=P1;i>-1;i--){
            char c = str.charAt(i);
            if (c == ' '){
                str.setCharAt(P2--, '0');
                str.setCharAt(P2--, '2');
                str.setCharAt(P2--, '%');
            }
            else
                str.setCharAt(P2--,c);
        }
        String str2 = str.toString();

        return str2;
    }
    public static void main(String args[]){
        StringBuffer str = new StringBuffer("");
        Solution s = new Solution();
        System.out.println(s.replaceSpace(str));
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值