《剑指offer》算法题整理(下):中等题、困难题

  力扣题库:跳转

一、队、栈

二、链表

35. 复杂链表的复制

请实现 copyRandomList 函数,复制一个复杂链表。在复杂链表中,每个节点除了有一个 next 指针指向下一个节点,还有一个 random 指针指向链表中的任意节点或者 null。

示例 1:

在这里插入图片描述

输入:head = [[7,null],[13,0],[11,4],[10,2],[1,0]]
输出:[[7,null],[13,0],[11,4],[10,2],[1,0]]

代码没调通

/*
// Definition for a Node.
class Node {
    int val;
    Node next;
    Node random;

    public Node(int val) {
        this.val = val;
        this.next = null;
        this.random = null;
    }
}
*/
class Solution {
    
    
    public Node copyRandomList(Node head) {
    
    
        //基本思路就是把每个结点在原地复制一个,然后再删掉原来那个
        if(head==null)return null;
        Node temp=head,free;
        //第一遍遍历复制结点
        while(temp!=null){
    
    
            free=new Node(temp.val);
            free.next=temp.next;
            temp.next=free;
            temp=free.next;
        }
        //第二遍遍历构建random指针
        temp=head;
        while(temp!=null){
    
    
            temp.next.random=temp.random==null?null:temp.random.next;
        }
        //第三遍遍历删掉重复的结点
        head=head.next;
        temp=head;
        while(temp!=null){
    
    
            if(temp.next!=null){
    
    
                temp.next=temp.next.next;
                temp=temp.next;
            }
            else break;
        }
        return head;
    }
}

三、树

07. 重建二叉树

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

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    
    
    public TreeNode buildTree(int[] preorder, int[] inorder) {
    
    
        return build(preorder,0,preorder.length-1,inorder,0,inorder.length-1);
    }
    public TreeNode build(int[] preorder,int i,int j,int[] inorder,int m,int n){
    
    
        if(preorder.length==0)return null;
        TreeNode root = new TreeNode(preorder[i]);
        int index=-1;
        for(int k=m;k<=n;++k){
    
    
            if(inorder[k]==root.val){
    
    
                index=k;break;
            }
        }
        if(index==-1)return null;
        if(index==m)root.left=null;
        else root.left=build(preorder,i+1,index-m+i,inorder,m,index-1);
        if(index==n)root.right=null;
        else root.right=build(preorder,index-m+i+1,j,inorder,index+1,n);
        return root;
    }
}

四、数组

56 - II. 数组中数字出现的次数 II

class Solution {
    
    
    public int singleNumber(int[] nums) {
    
    
        HashMap<Integer,Boolean> map=new HashMap<>(nums.length);
        for(int num:nums){
    
    
            if(map.containsKey(num))map.replace(num,true);
            else map.put(num,false);
        }
        for(int num:nums){
    
    
            if(!map.get(num))return num;
        }
        return -1;
    }
}

五、串

六、数学问题

64. 求1+2+…+n[中等]

求 1+2+…+n ,要求不能使用乘除法、for、while、if、else、switch、case等关键字及条件判断语句(A?B:C)。

class Solution {
    
    
    public int sumNums(int n) {
    
    
        boolean bool= n>0 && (n+=sumNums(n-1))>0;
        return n;
    }
}

七、哈希表

八、动态规划

47. 礼物的最大价值

在一个 m*n 的棋盘的每一格都放有一个礼物,每个礼物都有一定的价值(价值大于 0)。你可以从棋盘的左上角开始拿格子里的礼物,并每次向右或者向下移动一格、直到到达棋盘的右下角。给定一个棋盘及其上面的礼物的价值,请计算你最多能拿到多少价值的礼物?

class Solution {
    
    
    public int maxValue(int[][] grid) {
    
    
        for(int i=0;i<grid.length;++i){
    
    
            for(int j=0;j<grid[0].length;++j){
    
    
                if(i==0&&j==0)continue;
                else if(i==0)grid[i][j]=grid[i][j]+grid[i][j-1];
                else if(j==0)grid[i][j]=grid[i][j]+grid[i-1][j];
                else grid[i][j]=grid[i][j]+Math.max(grid[i][j-1],grid[i-1][j]);
            }
        }
        return grid[grid.length-1][grid[0].length-1];
    }
}

九、位运算

猜你喜欢

转载自blog.csdn.net/Tracycoder/article/details/112545714