算法题(2)--替换空格、从尾到头打印链表、重建二叉树

1.替换空格

请实现一个函数,将一个字符串中的每个空格替换成“%20”。例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy。
两个方法:
第一种:

public class Solution {
    public String replaceSpace(StringBuffer str) {
        return str.toString().replaceAll(" ","%20");
    }
}

第二种:

public class Solution {
    public String replaceSpace(StringBuffer str) {
          char[] chara = str.toString().toCharArray();
    String result ="";
    for (int i=0 ;i<str.length();i++) {
        String tmp = String.valueOf(chara[i]); 
        if(tmp.equals(" ")){
            result+="%20";
        }else {
            result +=tmp;
        }
    }
    return result;
    }
}

2.从尾到头打印链表

输入一个链表,按链表从尾到头的顺序返回一个ArrayList。

2.1 解题前要了解list的add方法
List接口中的add方法有如下两种重载方式:
① boolean add(E e);
② void add(int index, E element);
其中,方法①用于向列表的末尾插入新元素,这也是List接口中最常用的插入方法;方法②则可以在插入操作过程中指定插入的位置,此时,会自动将当前位置及只有的元素后移进行插入,需要注意的是,参数index的值不可大于当前list的容量,即在使用此方法填充一个list时,必须以0开始依次填充。
非递归用到方法②,递归方法就用到方法①。

2.2 要知道ListNode是什么。
ListNode
1)在节点ListNode定义中,定义为节点为结构变量。
2)节点存储了两个变量:value 和 next。value 是这个节点的值,next 是指向下一节点的指针,当 next 为空指针时,这个节点是链表的最后一个节点。
3)注意注意val只代表当前指针的值,比如p->val表示p指针的指向的值;而p->next表示链表下一个节点,也是一个指针。
4)构造函数包含两个参数 _value 和 _next ,分别用来给节点赋值和指定下一节点。

2.3 题解
(1)非递归方法
listNode 是链表,只能从头遍历到尾,但是输出却要求从尾到头,这是典型的"先进后出",我们可以想到栈!
ArrayList 中有个方法是 add(index,value),可以指定 index 位置插入 value 值,所以我们在遍历 listNode 的同时将每个遇到的值插入到 list 的 0 位置,最后输出 listNode 即可得到逆序链表
补充:

import java.util.ArrayList;
public class Solution {
    public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
       ArrayList list = new ArrayList();
        ListNode  tmp = listNode;
        while(tmp!=null){
            list.add(0,tmp.val);
            tmp = tmp.next;
        }
        return list;
    }
}

(2)递归方法

import java.util.ArrayList;
public class Solution {
    ArrayList list = new ArrayList();
    public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
       
        if(listNode!=null){
             printListFromTailToHead(listNode.next);
             list.add(listNode.val);
        }
        return list;
    }
}

3. 重建二叉树

输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。

3.1 在解题前要先弄懂二叉树的前序、中序、后序遍历是什么。
比如下面二叉树:

在这里插入图片描述
A:根节点,B:左子节点,C:右子节点
前序:A–B--C (根节点最先,同级子节点先左后右) —根左右
中序:B–A--C (先左子节点,在根节点,最后右子节点)—左根右
后序:B–C--A (先左,后右,再根)----左右根

再举个例子:
在这里插入图片描述
二叉树遍历结果
前序遍历:ABCDEFGHK
中序遍历:BDCAEHGKF
后序遍历:DCBHKGFEA

3.2 了解copyOfRange方法的用法
copyOfRange()—将指定数组的指定长度复制到一个新的数组
Arrays.copyOfRange()的格式如下 :
copyOfRange(int[] original, int from, int to)
第一个参数表示源数组
第二个参数表示开始位置(取得到)
第三个参数表示结束位置(取不到)

3.3 题解
前序遍历:根→左→右
中序遍历:左→根→右
前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},
1.前序第一个元素就是根节点 ,1就是根节点;
2. 中序中找到根节点1,1左边的元素就是左子树,1右边的元素就是右子树。
3. 接下来就是将左右子树都看成单独的二叉树,左子树的前序就是247,中序就是472,同理右子树 前序是3568,中序是5386。对左右子树重复1,2步最后就能重建出二叉树

import java.util.Arrays;
public class Solution {
    public TreeNode reConstructBinaryTree(int [] pre,int [] in) {
       //递归调用的终止条件
       if(pre.length == 0 || in.length == 0){
            return null;
       }
       //由前序遍历得到该二叉树的根结点
       TreeNode root = new TreeNode(pre[0]);
      
       //在中序遍历中找根结点位置,进行左右子树的划分
       for(int i = 0; i < in.length; i++){
           if(root.val == in[i]) {
            //将左子树看成一棵二叉树调用该方法,可以得到左子树根结点,即上面根结点的左子结点
            root.left = reConstructBinaryTree(Arrays.copyOfRange(pre,1,i+1),Arrays.copyOfRange(in,0,i));
            //将右子树看成一棵二叉树调用该方法,可以得到右子树根结点,即上面根结点的右子结点
            root.right = reConstructBinaryTree(Arrays.copyOfRange(pre,i+1,pre.length),Arrays.copyOfRange(in,i+1,in.length));
            //找到根结点位置便跳出循环
            break;
           }
       }
       //返回根结点
       return root;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值