剑指OFFER76题,依次更新中

36 篇文章 3 订阅
2 篇文章 0 订阅

剑指OFFER

1.找出数组中重复的数字

class Solution {
       public int duplicateInArray(int[] nums) {
        int len = nums.length;
        if(nums==null||len==0)
            return -1;

        for(int i =0;i<len;i++){
            if(nums[i]<0||nums[i]>len-1)
                return -1;
        }
        
        for(int i = 0;i<len;i++){
            while(nums[i]!=i){
                if(nums[i]==nums[nums[i]])
                    return nums[i];
                    
                int temp = nums[i];
                nums[i] = nums[temp];
                nums[temp] = temp;
            }
        }

        return -1;
    }

}

2.不修改数组找出重复的数字

class Solution {
    public int duplicateInArray(int[] nums) {
        int l = 1,r = nums.length-1;
        while(l < r){
            int mid = l+r >> 1;
            int s = 0;
            for(int x:nums){
                if(x>=l&&x<=mid){
                    s++;
                }
            }
            if(s>mid-l+1){
                r = mid;
            }else{
                l = mid+1;
            }
        }
        return r;
    }
}

3. 二维数组中的查找

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

4.替换空格

class Solution {
    public String replaceSpaces(StringBuffer str) {
        int x = str.indexOf(" ");
        if(x!=-1){
            replaceSpaces(str.replace(x,x+1,"%20"));
        }
        return str.toString();
    }
}
class Solution {
    public String replaceSpace(String s) {
        s = s.replace(" ","%20");
        return s;
    }
}
class Solution {
    public String replaceSpace(String s) {
        s = s.replaceAll("\\s","%20");
        return s;
    }
}

5.从尾到头打印链表

class Solution {
    public int[] reversePrint(ListNode head) {
//        先判断链表的数量
        ListNode tmp = head;
        int cnt = 0;
        while(tmp!=null){
            tmp = tmp.next;
            cnt++;
        }
        int[] arr = new int[cnt];
        for(int i = cnt-1; i >= 0; i--){
            arr[i] = head.val;
            head = head.next;
        }
        return arr;
    }
}
//leetcode submit region end(Prohibit modification and deletion)

6.重建二叉树

前序遍历:中左右 根据前序遍历可知道根节点

中序遍历:左中右

后序遍历:左右中

解题步骤:

1.根据前序遍历可以知道根节点的位置,第一个值就是根节点的位置;

2.在中序遍历中找到根节点的位置,根节点左边是左子树的中序遍历,根节点右边是右子树的中序遍历。

3.假设左子树的中序遍历的长度为l,则在 前序遍历中,根节点后面的l个数为左子树的前序遍历,剩下的是右子树的前序遍历。

4.有了左右子树的前序遍历和中序遍历,我们可以递归创建出左右子树,然后再创建根节点。

/**
 * Definition for a binary tree node.
 * class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    int[] preorder;
    int[] inorder;
    HashMap<Integer,Integer> map;
    public TreeNode buildTree(int[] preorder, int[] inorder) {
        
        this.preorder = preorder;
        this.inorder = inorder;
        map = new HashMap<Integer,Integer>();
        for(int i = 0; i < inorder.length; i++){
            map.put(inorder[i],i);
        }
        return dfs(0,preorder.length-1,0,inorder.length-1);
    }
    public TreeNode dfs(int pl,int pr,int il,int ir){
        if(pl > pr){
            return null;
        }
        TreeNode res = new TreeNode(preorder[pl]);
        int k = map.get(res.val);
        res.left = dfs(pl+1,pl+k-il,il,k-1);
        res.right = dfs(pl+k-il+1,pr,k+1,ir);
        return res;
    }
}

7.二叉树的下一个节点

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode father;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    public TreeNode inorderSuccessor(TreeNode p) {
        // 存在右孩子,后继就是右子树中最左侧的点
        if(p.right!=null){
             p = p.right;
             while(p.left!=null){
                  p = p.left;
             }
             return p;
        }
        while(p!=null&&p.father!=null&&p!=p.father.left){
            p = p.father;
        }
        return p.father;
        
    }
}	

8.用两个栈实现队列

class MyQueue {
    Stack <Integer> s1;
    Stack <Integer> s2;
    /** Initialize your data structure here. */
    public MyQueue() {
        s1 = new Stack<>();
        s2 = new Stack<>();
    }
    
    /** Push element x to the back of queue. */
    public void push(int x) {
        s1.push(x);
    }
    
    /** Removes the element from in front of queue and returns that element. */
    public int pop() {
        while(!s2.empty()){
            return s2.pop();
        }
        while(!s1.empty()){
            s2.push(s1.pop());
        }
        return s2.pop();
    }
    
    /** Get the front element. */
    public int peek() {
        while(!s2.empty()){
            return s2.peek();
        }
        while(!s1.empty()){
            s2.push(s1.pop());
        }
        return s2.peek();
    }
    
    /** Returns whether the queue is empty. */
    public boolean empty() {
        return s1.isEmpty()&&s2.isEmpty();
    }
}

/**
 * Your MyQueue object will be instantiated and called as such:
 * MyQueue obj = new MyQueue();
 * obj.push(x);
 * int param_2 = obj.pop();
 * int param_3 = obj.peek();
 * boolean param_4 = obj.empty();
 */

9.斐波那契数列

class Solution {
    public int Fibonacci(int n) {
         if(n<=0){
             return 0;
         }
         if(n<=2){
             return 1;
         }
         int a = 1, b = 1, c = 0 ;
         for(int i = 3; i <= n; i++){
             c = a+b;
             a = b;
             b = c;
         }
         return c;
    }
}

10.旋转数组的最小数字

class Solution {
    public int findMin(int[] nums) {
        //先去除右边界
        int n = nums.length-1;
        if(n<0){
            return -1;
        }
        while(nums[0]==nums[n]&&n>0){
            n--;
        }
        if(nums[n]>=nums[0]){
            return nums[0];
        }
        int l = 0, r = n;
        while(l < r){
            int mid = l + r >> 1;
            if(nums[mid]<nums[0]){
                r = mid;
            }else{
                l = mid+1;
            }
        }
        return nums[r] ;
    }
}

11.矩阵中的路径

class Solution {
    public boolean hasPath(char[][] matrix, String str) {
        for(int i=0;i<matrix.length;i++)
        {
            for(int j=0;j<matrix[i].length;j++)
            {
                if(dfs(matrix,str,0,i,j))//将每一个字母作为开始看是否匹配
                return true;
            }
        }
        return false;
    }
    public boolean dfs(char[][] matrix,String str,int u,int x,int y){
        if(matrix[x][y]!=str.charAt(u)) return false;//第一个不匹配,
        if(u==str.length()-1) return true;//已经遍历到字符串后一个字母了
        int dx[]=new int[]{-1,0,1,0},dy[]=new int[]{0,1,0,-1};//左,上,右,下的左边计算
        char t = matrix[x][y];//取出正在比较的值进行标记
        matrix[x][y]='#';
        //要进行正式的比较的的逻辑
        for(int i=0;i<4;i++){//分别计算四个方向
            int a =x+dx[i],b =y+dy[i];
            if(a>=0&&a<matrix.length&&b>=0&&b<matrix[a].length)
            if(dfs(matrix,str,u+1,a,b)) return true;
        }
        matrix[x][y]=t;
        return false;
    }
}

12.机器人的运动范围

class Solution {
    int count=0;
    public int movingCount(int threshold, int rows, int cols)
    {
        if(rows==0||cols==0)return 0;
        boolean [][] vt=new boolean[rows][cols];
        dfs(threshold,rows,cols,0,0,vt);
        return count;
    }

    void  dfs(int threshold,int rows,int cols,int x,int y,boolean [][]vt){

        if(sum(x)+sum(y)>threshold)return;
        int [] dx={-1,0,1,0};
        int [] dy={0,1,0,-1};
        vt[x][y]=true;
        count++;
        for(int i=0;i<4;i++){
            int nx=x+dx[i];
            int ny=y+dy[i];
            if(nx>=0&&nx<rows&&ny>=0&&ny<cols&&vt[nx][ny]==false){
                dfs(threshold,rows,cols,nx,ny,vt);

            }
        }

    }

    int sum(int a){
        int b=0;
        while(a>0){
            b+=a%10;
            a/=10;
        }
        return b;
    }

13.剪绳子


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值