栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

剑指offer刷题(中等等级)

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

剑指offer刷题(中等等级)

()(1)二维数组中的查找

(2)重建二叉树

利用Arrays.copyOfRange(n,from,to)进行数组截取,实现起来更简便。

public TreeNode reConstructBinaryTree(int [] pre,int [] vin) {
        int pren = pre.length;
        int vinn = vin.length;
        if(pren==0 || vinn==0)
            return null;
        int node = pre[0];
        TreeNode root = new TreeNode(node);
        for(int i = 0;i 

(3)二叉树的下一个结点 

(4)矩阵中的路径

更简便的代码:
1、将矩阵路径经过时改为‘.’,使用完再回复为原值。来代替flag矩阵记1

2、关于i,j是否超届的判断均放到最开始的if中用,超届则直接false;

3、易错点,到index最后一位匹配上就直接给true

public boolean hasPath (char[][] matrix, String word) {
        for(int i=0;i=m.length||j<0||j>=m[0].length||m[i][j]!=word.charAt(index))
            return false;
        if(index==word.length()-1)
            return true;
        char t = m[i][j];
        m[i][j] = '.';
        boolean res = deepPath(m,i-1,j,word,index+1)||
            deepPath(m,i+1,j,word,index+1)||
            deepPath(m,i,j-1,word,index+1)||
            deepPath(m,i,j+1,word,index+1);
        m[i][j]=t;
        return res;
    }

(5)剪绳子 

动态规划的思想是一定要从最小子问题开始求解,之后更大的问题可以应用其子问题的结果。

若该子问题出现多次,只需计算一次。

1、本题n=2和n=3与裁成了2和3的值不同。

因为n=2和n=3必须进行裁剪故对应1,2。但裁的段中有2和3时不需要继续裁最大为2,3.

其他的可以依次便利或得(不必排除裁成长度为1的段,因为肯定不如其他的值大)

public int cutRope (int n) {
        // write code here
        if(n==2)
            return 1;
        if(n==3)
            return 2;
        int[] max = new int[n+1];
        max[1] = 1;
        max[2] = 2;
        max[3] = 3;
        for(int i = 4;i<=n;i++){
            for(int j=1;j 

(6) 数值的整数次方

注意指数为负数时

(7)调整数组顺序使奇数位于偶数前面(一)

注意此题是调整后保持奇偶数内部的相对位置

(8)链表中环的入口结点

这里忽视的问题是,slow走一步,fast走两步是slow=pHead.next,fast=pHead.next.next;

错误1:slow=pHead,fast=pHead.next.next;这相当于slow一步没走

错误2:在一起走c步时,从pHead开始

(9)树的子结构

重点看一下递归部分。易忽略,如果一开始root1==null则肯定是false

public boolean HasSubtree(TreeNode root1,TreeNode root2) {
        if(root1==null||root2==null)
            return false;
        Stack stack1 = new Stack();
        stack1.push(root1);
        while(!stack1.isEmpty()){
            TreeNode node = stack1.pop();
            if(isSame(node,root2)){
                return true;
            }
            if(node.left!=null)
                stack1.push(node.left);
            if(node.right!=null)
                stack1.push(node.right);
        }
        return false; 
    }
    public boolean isSame(TreeNode node,TreeNode root2){
        if(node==null&&root2!=null)
            return false;
        if(root2==null)
            return true; 
        if(node.val!=root2.val)
            return false;    
        return isSame(node.left,root2.left)&&isSame(node.right,root2.right);
    }

(10)栈的压入、弹出序列

空间复杂度小的方式:与用栈辅助思想一致,但时利用数组已经入栈的部分当作栈。

top指向栈顶,pushIndex指向下一个要操作的数

 public boolean IsPopOrder(int [] pushA,int [] popA) {
        if(pushA.length==0)
            return true;
        int pushIndex = 0,top=-1,popIndex=0;
        while(popIndex=0&&popA[popIndex]==pushA[top]){
                top--;
                popIndex++;
            }
            else{
                if(pushIndex>=pushA.length)
                    return false;
                else{
                    pushA[++top]=pushA[pushIndex];
                    pushIndex++;
                }
            }
        }
        return true;
    }

(11)二叉搜索树的后序遍历序列

对于使用stack实现的得递归方法,不理解

(12)二叉树中和为某一值的路径(二)

此题递归与利用队列时间控件复杂度一致,且非递归实现起来麻烦,故仅练习了递归。

(13)二叉搜索树与双向链表

1、采用中序遍历的思想,这样便利结束才是有序的

2、利用head记录第一个节点,用pre记录遍历序列的前一个节点。注意当需要对pre进行更新时,pre为null,此时遍历序列的第一个节点记为head;

3、不要陷入要记录后一个节点的误区,无法做到。变通即pre.right指向现在的,现在的left指向pre。

递归方法实现:

 private TreeNode head = null;
    private TreeNode pre = null;
    public TreeNode Convert(TreeNode pRootOfTree) {
        if(pRootOfTree==null)
            return null;
        convert(pRootOfTree);
        return head;
    }
    public void convert(TreeNode root){
        if(root==null)
            return ;
        convert(root.left);
        if(pre == null){
            head = root;
        }
        else{
           pre.right = root;
           root.left = pre;
        }
        pre = root;
        convert(root.right);
    }

非递归方法:也可以看作用栈实现中序遍历

1、当指针不为空,或栈不为空都要继续进行操作

2、利用while将当前指向的节点左子节点进栈,直到再无左子树

      此指针为空,或进栈到再无左子树。进行出栈(此时对出栈节点操作与递归的一致)

3、将指针指向当前出栈节点的右孩子,

        因为此时此节点的左孩子一定已经进行过操作,下一个要操作的是右孩子

即每次都遍历到此节点最左,操作完成,指向当前节点右孩子,循环往复。 

public TreeNode Convert(TreeNode pRootOfTree) {
        if(pRootOfTree==null)
            return null;
        TreeNode head = null;
        TreeNode pre = null;
        Stack stack = new Stack();
        while(pRootOfTree!=null||!stack.isEmpty()){
           while(pRootOfTree!=null){
               stack.push(pRootOfTree);
               pRootOfTree = pRootOfTree.left;
           }
            TreeNode node = stack.pop();
            if(pre==null)
                head = node;
            else{
                pre.right = node;
                node.left = pre;
            }
            pre = node;
            pRootOfTree = node.right;
        }
        return head;
    }

(14) 字符串的排列

一种更为简便的方法,利用字符串的子串获取与拼接。

递归传到现在的新串,剩余的字母,ArrayList

这里注意,ArrayList在函数中传递是地址的拷贝,不是仅仅参数的拷贝

 public ArrayList Permutation(String str) {
        ArrayList result = new ArrayList();
        if(str==null||str.length()==0)
            return null;
        newString(str,"",result);
        return result;
    }
    public void newString(String str,String newstr,ArrayList result){
        if(str.length()==0){
            if(!result.contains(newstr.toString()))
                result.add(newstr.toString());
            return ;
        }
        for(int i = 0;i 

(15)最小的K个数

本题可利用三种方法实现:堆排序,有控制的快排,冒泡

对于堆排序思想:要用大顶推,因为堆顶的值是方便获取的,每次要看是不是前4小,就要看是不是比目前进堆的最大值还小,故要用大顶堆。

  
    public ArrayList GetLeastNumbers_Solution(int [] input, int k){
        ArrayList res = new ArrayList();
        if(input.length==0||k==0)
            return res;
        Queue queue = new PriorityQueue((o1,o2)->(o2-o1));
        for(int i=0;i 

(16) 数据流中的中位数

提议目的理解清楚

ArrayList的add可以在对应位置添加(即插入元素)

 private ArrayList res = new ArrayList();
    public void Insert(Integer num) {
        int index = 0;
        if(res.isEmpty())
            res.add(num);
        else{
            while(index 

(17) 

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/955450.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号