剑指Offer题目汇总(持续更新中...)

知识点与解题思路

  • 1、剑指Offer-03 数组中重复的数字
    • (1)Hashset的使用
  • 2、剑指Offer-04 二维数组中的查找
    • (1)二维数组的使用
  • 3、剑指Offer-05 替换空格
    • (1)StringBuilder的使用
    • (2)字符串与数组之间的转换
  • 4、剑指 Offer 06. 从尾到头打印链表
    • (1)Java中栈的使用
  • 5、剑指 Offer 07. 重建二叉树
  • 6、剑指 Offer 09. 用两个栈实现队列
    • (1)Java中栈的使用
  • 7、剑指 Offer 10- I. 斐波那契数列
    • (1)动态规划
  • 8、剑指 Offer 10- II. 青蛙跳台阶问题
    • (1)动态规划
  • 9、剑指 Offer 11. 旋转数组的最小数字
    • (1)二分查找
  • 10、剑指 Offer 12. 矩阵中的路径
    • (1)DFS+可行性剪枝
  • 11、剑指 Offer 13.机器人的运动范围
    • (1)DFS+可行性剪枝
  • 12、剑指 Offer 14- I. 剪绳子
    • (1)动态规划
    • (2)贪心算法
    • (3)大数取余
  • 13、剑指 Offer 15. 二进制中1的个数
    • (1)位运算
    • (2)Integer类的使用
  • 14、剑指 Offer 16. 数值的整数乘方
    • (1)递归
    • (2)Java中幂运算
  • 15、剑指 Offer 17. 打印从1到最大的n位数(简单)
  • 16、剑指 Offer 18. 删除链表的节点(简单)
  • 17、剑指 Offer 19. 正则表达式匹配(困难)
  • 18、剑指 Offer 20. 表示数值的字符串
    • (1)String类的常用方法.

1、剑指Offer-03 数组中重复的数字

剑指Offer题目汇总(持续更新中...)_第1张图片
一、知识点

(1)Hashset的使用

二、解题思路

class Solution {
    public static int findRepeatNumber(int[] nums) {
        HashSet<Integer> set = new HashSet<>();
        for (int i=0;i<nums.length;i++){
            if (set.add(nums[i])==false){
                return nums[i];
            }
        }
        return -1;

        }
}

2、剑指Offer-04 二维数组中的查找

剑指Offer题目汇总(持续更新中...)_第2张图片

一、知识点

(1)二维数组的使用

  • 创建二维数组的方法:int [][] array = new int[6][6];int [][] array = {{1,2,3},{1,2,3},{1,2,3}};
  • 获取二维数组的行:matrix.length;
  • 获取二维数组的列:matrix[0].length;

二、解题思路

class Solution {
    public boolean findNumberIn2DArray(int[][] matrix, int target) {
        //获取二维数组的长和宽
        int length = matrix.length;
        if(length==0) return false;
        int width = matrix[0].length;
        if(width==0) return false;
        for(int i=0;i<length;i++){
            if(target>=matrix[i][0] & target<=matrix[i][width-1]) {
                for(int j =0 ;j<width;j++){
                    if(target==matrix[i][j]) return true;
                }
            }
        }
        return false;
    }
}

3、剑指Offer-05 替换空格

剑指Offer题目汇总(持续更新中...)_第3张图片
一、知识点

(1)StringBuilder的使用

(2)字符串与数组之间的转换

二、解题思路

class Solution {
    public String replaceSpace(String s) {
        //创建一个StringBUilder,保存结果
        StringBuilder result = new StringBuilder();
        for(Character x : s.toCharArray()){
            if(x==' ') result.append("%20");
            else result.append(x);
        }
        return result.toString();

    }
}

4、剑指 Offer 06. 从尾到头打印链表

剑指Offer题目汇总(持续更新中...)_第4张图片

一、知识点

(1)Java中栈的使用

二、解题思路

class Solution {
    public int[] reversePrint(ListNode head) {
        LinkedList<Integer> stack = new LinkedList<Integer>();
        while(head!=null){
            stack.addFirst(head.val);
            head=head.next;
        }
        int[] res = new int[stack.size()];
        for(int i=0;i<res.length;i++){
            res[i] = stack.removeFirst();
        }
        return res;
    }
}

5、剑指 Offer 07. 重建二叉树

6、剑指 Offer 09. 用两个栈实现队列

剑指Offer题目汇总(持续更新中...)_第5张图片
一、知识点

(1)Java中栈的使用

二、解题思路

  1. 使用LinkedList实现栈A、B;

  2. 通过 A栈进行入队操作,只需执行进栈操作即可;

  3. 通过B栈进行出队操作,由于要实现队列,需要将A栈中的元素出栈进去B栈,此时B中的元素为倒序;出队时只需要执行B栈的出栈操作即可;

  4. 当B中还存在元素时,直接进行出栈即可;

class CQueue {
    LinkedList<Integer> A, B;
    public CQueue() {
        A = new LinkedList<Integer>();
        B = new LinkedList<Integer>();
    }
    public void appendTail(int value) {
        A.addLast(value);
    }
    public int deleteHead() {

        //若B是非空,表明B中已存在倒序元素,直接进行出栈
        if(!B.isEmpty()) return B.removeLast();

        //若A也是空,返回-1
        if(A.isEmpty()) return -1;

        //将A中的元素倒序放入B中
        while(!A.isEmpty()){
            B.addLast(A.removeLast());
        }
        return B.removeLast();
    }
}

7、剑指 Offer 10- I. 斐波那契数列

剑指Offer题目汇总(持续更新中...)_第6张图片
一、知识点

(1)动态规划

二、解题思路

class Solution {
    public int fib(int n) {
        int a=0;
        int b=1;
        int sum;
        for(int i=0;i<n;i++){                 
            sum = (a+b)%1000000007;
            a=b;
            b=sum;
        }
        return a;
    }
}

8、剑指 Offer 10- II. 青蛙跳台阶问题

剑指Offer题目汇总(持续更新中...)_第7张图片
一、知识点

(1)动态规划

二、解题思路

  1. n个台阶的跳法可以由(n-1)个台阶和(n-2)个台阶推出,得递推关系式为:f(n) = f(n-1) + f(n-2)
  2. 使用动态规划进行解题。
class Solution {
    public int numWays(int n) {
        int a=1;
        int b=2;
        int sum;
        for(int i=0;i<n-1;i++){
            sum =(a+b)%1000000007;
            a=b;
            b=sum;
        }
        return a;

    }
}

9、剑指 Offer 11. 旋转数组的最小数字

剑指Offer题目汇总(持续更新中...)_第8张图片
一、知识点

(1)二分查找

二、解题思路

方法1:遍历找旋转点

class Solution {
    public int minArray(int[] numbers) {
        int result=numbers[0];
        for(int i=0;i<numbers.length-1;i++){
            if(numbers[i]>numbers[i+1]){
                result = numbers[i+1];
                break;
            }
            
        }
        return result;

    }
    
}

方法二:二分查找

class Solution {
    public int minArray(int[] numbers) {
        int L=0;
        int R=numbers.length-1;
        int mid;
        while(L<R){
            mid = L + (R-L)/2;
            if(numbers[mid]>numbers[R]) L=mid+1;
            else if(numbers[mid]<numbers[R]) R=mid;
            else R--;
        }
        return numbers[R];
        
    }
}

10、剑指 Offer 12. 矩阵中的路径

剑指Offer题目汇总(持续更新中...)_第9张图片
一、知识点

(1)DFS+可行性剪枝

二、解题思路

11、剑指 Offer 13.机器人的运动范围

剑指Offer题目汇总(持续更新中...)_第10张图片
一、知识点

(1)DFS+可行性剪枝

二、解题思路

class Solution {
    
    int res;
    boolean[][] marked;
    public int movingCount(int m, int n, int k) {
        marked = new boolean[m][n];
        dfs(0,0,m,n,k);
        return res;
        
    }
    public void dfs(int x,int y, int m, int n ,int k){
        if(x>=m || y>=n || marked[x][y] || sum(x)+sum(y)>k) return;
        marked[x][y] = true;
        res++;
        dfs(x+1,y,m,n,k);
        dfs(x,y+1,m,n,k);

    }
    public int sum(int x){
        int sum = 0;
        while(x!=0){
            sum+=x%10;
            x=x/10;
        }
        return sum;
    }
}

12、剑指 Offer 14- I. 剪绳子

剑指Offer题目汇总(持续更新中...)_第11张图片
一、知识点

(1)动态规划

(2)贪心算法

(3)大数取余

二、解题思路

思路一:动态规划(1

  1. 将长度为 i 的绳子分成 j 和 i-j ,那么 dp[i] 可以由 j 和 i-j推出,其中 j 和 i-j可能需要再分,也可能不需要再分,要根据 j 与 dp[j] 的大小关系进行确定;
  2. dp[i] = max { dp[j] , j }* max { dp[i-j] , i-j }
  3. 对j从2至i/2进行遍历,选择结果最大的切割方案。
class Solution {
    public int cuttingRope(int n) {
        if(n==2) return 1;
        int[] dp = new int[n+1];
        dp[2] = 1;
        dp[3]=2;
        for(int i=4;i<n+1;i++){
            int max = 0;
            for(int j=2; j<=i/2;j++){
                int temp = Math.max(dp[j],j)*Math.max(dp[i-j],i-j);
                if(temp>max) max =temp;
            }
            dp[i]=max;
        }
        return dp[n];

    }
}

思路二:贪心算法(1

  1. 切割出来的小段绳子中,长度为3的越多,结果越大;
  2. 使用循环求余法进行求余;
class Solution {
    public int cuttingRope(int n) {
        long res=1;  //由于res*3可能超出int32的范围,例如res=1000000006,因此使用long类型
        if(n==2) return 1;
        if(n==3) return 2;
        while(n>4){
            res*=3;
            res = res%1000000007;
            n=n-3;
        }
        return (int)(res*n%1000000007);   //出循环之后,n的可能取值:n = 2,3,4
    }
}

13、剑指 Offer 15. 二进制中1的个数

剑指Offer题目汇总(持续更新中...)_第12张图片
一、知识点

(1)位运算

  • 与:&
  • 或:|
  • 非:~
  • 异或:^
  • 移位:左移n位(<>n)

(2)Integer类的使用

  • 十进制转化为二进制:String s = Integer.toBinaryString( int i );
  • 十进制转化为八进制:String s = Integer.toOctalString( int i );
  • 十进制转化为十六进制:String s = Integer.toHexString( int i );
  • 化为十进制:Integer.valueOf (String s, int radix),例如:int x = Integer.valueOf(“0101”,2);
  • 统计二进制中1的个数:int num = Integer.bitCount( int i );

二、解题思路

思路一:移位法

  1. 将数字n与1进行&运算,可以判断n的末尾是否为1;
  2. n = n >>1 ,将n右移一位,再通过步骤一判断n的右2位是否为1;
  3. 依次进行判断。
public class Solution {
    // you need to treat n as an unsigned value
    public int hammingWeight(int n) {
        int num =0;
        for(int i =0 ; i< 32 ; i++){
            if((n&1)==1) num++;
            n=n>>1;
        }
        return num;        
    }
}

思路二:消1法

  1. n&(n-1) 相当于将n最右侧的1变为0,从而消除一个1;
  2. 可以消几次就代表有多少个1。
public class Solution {
    // you need to treat n as an unsigned value
    public int hammingWeight(int n) {
        int num =0;
        while(n!=0){
            num++;
            n=n&(n-1);
        }
        return num;
        
    }
}

思路三:使用 Integer.bitCount()

public class Solution {
    // you need to treat n as an unsigned value
    public int hammingWeight(int n) {
        return Integer.bitCount(n);
    }
}

14、剑指 Offer 16. 数值的整数乘方

剑指Offer题目汇总(持续更新中...)_第13张图片
一、知识点

(1)递归

(2)Java中幂运算

  • Math.pow(2,4) :2^4=16.0

二、解题思路

思路一:递归

class Solution {
    public double myPow(double x, int n) {
        if(n==0) return 1.0;
        if(n<0) return 1/(x*myPow(x,-n-1));
        else if(n%2==1) return x*myPow(x,n-1);
        return myPow(x*x,n/2);
    }
}

15、剑指 Offer 17. 打印从1到最大的n位数(简单)

剑指Offer题目汇总(持续更新中...)_第14张图片
解题思路

class Solution {
    public int[] printNumbers(int n) {
        int end = (int)Math.pow(10,n)-1;
        int[] res = new int[end];
        for(int i = 0; i< end; i++) res[i] = i+1;
        return res;  
    }
}

16、剑指 Offer 18. 删除链表的节点(简单)

剑指Offer题目汇总(持续更新中...)_第15张图片
解题思路

class Solution {
    public ListNode deleteNode(ListNode head, int val) {
        if(head.val == val) return head.next;
        ListNode pre = head, cur = head.next;
        while(cur != null && cur.val != val) {
            pre = cur;
            cur = cur.next;
        }
        if(cur != null) pre.next = cur.next;
        return head;
    }
}

17、剑指 Offer 19. 正则表达式匹配(困难)

18、剑指 Offer 20. 表示数值的字符串

剑指Offer题目汇总(持续更新中...)_第16张图片

一、知识点

(1)String类的常用方法.

二、解题思路

class Solution {
    public boolean isNumber(String s) {
        s = s.trim();
        if(s.contains("e")){
            String[] arr = s.split("e",2);
            if(arr.length!=2) return false;
            else return (isInt(arr[0]) || isDecimal(arr[0])) && isInt(arr[1]);
        }
        else if(s.contains("E")){
            String[] arr = s.split("E",2);
            if(arr.length!=2) return false;
            else return (isInt(arr[0]) || isDecimal(arr[0])) && isInt(arr[1]);
        }
        else if(s.contains(".")) return isDecimal(s);
        return isInt(s);

    }
    public boolean isDecimal(String s){
        int n = s.length();
        String temp = "0123456789";
        if(n==0) return false;
        else if(!s.contains(".")) return false;
        String[] arr = s.split("\\.",2);
        if(arr.length==1) return isInt(arr[0]);
        else if(arr.length==2){
            if(arr[0].equals("")) return isIntNumber(arr[1]);
            else if(arr[0].equals("+")) return isIntNumber(arr[1]);
            else if(arr[0].equals("-")) return isIntNumber(arr[1]);
            else if(arr[1].equals("")) return isInt(arr[0]);
            else return isInt(arr[0]) && isIntNumber(arr[1]);
        }
        else return false;
    }

    public boolean isInt(String s) {
        int n = s.length();
        String temp = "0123456789";
        if(n==0) return false;
        else if(s.charAt(0)=='+' || s.charAt(0)=='-'){
            if(n==1) return false;
            for(int i=1; i<n; i++){
                if(!temp.contains(""+s.charAt(i))) return false;
            }
            return true;
        }
        for(int i=0; i<n; i++){
            if(!temp.contains(String.valueOf(s.charAt(i)))) return false;
            }
        return true;     
    }

    public boolean isIntNumber(String s) {
        int n = s.length();
        String temp = "0123456789";
        if(n==0) return false;
        for(int i=0; i<n; i++){
            if(!temp.contains(String.valueOf(s.charAt(i)))) return false;
            }
        return true;     
    }
}

你可能感兴趣的:(Java数据结构与算法,算法,leetcode,数据结构)