589. N 叉树的前序遍历 / 144. 二叉树的前序遍历 / 2. 两数相加 / 93. 复原 IP 地址

589. N 叉树的前序遍历【简单题】【每日一题】

思路:【递归】

  1. 定义递归函数recursion,判断当前节点是否为空,如果不是空,那么将当前节点的值添加到 list 中,并挨个遍历其子节点,调用recursion函数对其子节点执行同样的操作;当前节点如果为空,则递归终止,递归函数返回。
  2. 在preorder函数中,新建列表list,调用recursion函数,最后返回list。

代码:

/*
// Definition for a Node.
class Node {
    public int val;
    public List<Node> children;

    public Node() {}

    public Node(int _val) {
        val = _val;
    }

    public Node(int _val, List<Node> _children) {
        val = _val;
        children = _children;
    }
};
*/

class Solution {
    public List<Integer> preorder(Node root) {
        List<Integer> list = new ArrayList<>();
        recursion(list,root);
        return list;
    }
    public void recursion(List<Integer> list , Node root){
        if(root == null){
            return;
        }
        list.add(root.val);
        for(Node child : root.children){
            recursion(list,child);
        }
    }
}

144. 二叉树的前序遍历【简单题】

思路:【递归】

  1. 定义递归函数recursion,如果当前节点不为空,则list添加当前节点的值,并依次递归当前节点的左节点和右节点;如果当前节点为空,则递归终止,recursion函数返回。
  2. 在preorderTraversal函数中,新建列表list,调用递归函数recursion,返回list。

代码:

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public List<Integer> preorderTraversal(TreeNode root) {
        List<Integer> list = new ArrayList<>();
        recursion(list,root);
        return list;
    }
    public void recursion(List<Integer> list , TreeNode root){
        if(root == null){
            return;
        }
        list.add(root.val);
        recursion(list,root.left);
        recursion(list,root.right);
    }
}

2. 两数相加【中等题】

思路:

  1. 声明链表头head和尾tail,此时两者都为null,定义进位标志位plus,初值为0。
  2. 只要链表l1和l2有一个不为空,两数相加的过程就继续进行。
  3. 定义 v1 为 l1 的值,l1为空时 v1=0;定义 v2 为 l2 的值, l2为空时 v2 = 0;定义sum即为两个链表的逆向和,sum = v1+v2+plus;
  4. 如果头部head为空,即还没有头部,那就创建一个头部,即把头部赋值为当前的sum % 10,同时答案链表只有一个节点,因此头部也是尾部,于是tail = head;
  5. 如果头部head不为空,说明答案链表已经创建,那么我们只需在答案链表的尾部追加一个尾结点,赋值为当前的sum % 10,并将尾部更新。
  6. 进位标志位plus更新为 sum / 10;如果链表 l1 当前节点不为空,那么将 l1 更新到下一个节点;如果链表 l2 当前节点不为空,那么将 l2 更新到下一个节点。
  7. 当 l1 和 l2 同时为空时,说明两个链表相加完毕,此时退出while循环,返回答案链表,即头部为head的链表,即返回head。

代码:

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        ListNode head = null,tail = null;
        int plus = 0;
        while(l1 != null || l2 != null){
            int v1 = l1 == null ? 0 : l1.val;
            int v2 = l2 == null ? 0 : l2.val;
            int sum = v1 + v2 + plus ;
            if(head == null){
                head = new ListNode(sum % 10);
                tail = head;
            }else{
                tail.next = new ListNode(sum % 10);
                tail = tail.next;
            }
            plus = sum / 10;
            if(l1 != null){
                l1 = l1.next;
            }
            if(l2 != null){
                l2 = l2.next;
            }
        }
        if(plus > 0){
            tail.next = new ListNode(plus);
        }
        return head;
    }
}

93. 复原 IP 地址【中等题】

思路:【回溯】

  1. 定义回溯函数dfs:
  2. 有效的IP地址肯定是四段,于是将搜索分为4个部分,用一个长度为4的数组来存放搜索到的合法的ip地址分段,并需要一个id来记录当前搜索到了ip地址的第几段,这个id刚好与存放合法ip地址数组的下标一一对应,另外,在回溯搜索字符串的时候,需要一个变量start来记录当前从什么位置开始搜索字符串。
  3. 当id等于4时,说明已经搜索到了4个合法的ip地址分段,如果此时字符串的搜索开始位置start=s.length(),说明这四个分段是字符串的ip资质形式的一种有效情况,将这4个分段组成ip地址形式的字符串,添加进list列表中;如果此时字符串的搜索开始位置start
    < s.length(),这说明虽然已经找到4个合法分段,但字符串还有字符没有使用,而这种情况是非法的,于是直接return,回溯到上一步。
  4. 当id<4时,如果start = s.length(),说明这4个分段还没找够字符串就遍历完了,那么此时也需要return,回溯到上一步。
  5. 如果当前数字是0,那么这个ip地址分段只能是0,将当前分段的搜索结果置0之后,开始下一段搜索。
  6. 上述3种情况排除之后,下面就是最一般的情况,枚举所有可能的ip地址分段:
  7. 从搜索开始位置start开始,逐个长度截取子串,转为int类型,判断这个分段是否是合法的ip地址分段,(大于0且小于等于255即为合法分段),如果是合法分段,就将当前这个分段地址添加到当前分段位置的segments中,并将要搜索的分段位置即id+1,要搜索的字符位置即start更新为i+1,递归调用dfs函数,查找下一个分段;如果不是合法分段,那么直接直接退出当前循环,回溯到上一层dfs函数中。

代码:

class Solution {
    public List<String> restoreIpAddresses(String s) {
        List<String> list = new ArrayList<>();
        int[] segments = new int[4];
        dfs(0,0,s,list,segments);
        return list;
    }
    public void dfs(int id,int start,String s,List<String> list,int[] segments){
        if (id == 4){
            if (start == s.length()){
                StringBuilder sb = new StringBuilder();
                for (int i = 0; i < 4; i++) {
                    sb.append(segments[i]);
                    if (i != 3){
                        sb.append('.');
                    }
                }
                list.add(sb.toString());
            }
            return;
        }
        if (start == s.length()){//如果还没找够4段IP地址就已经遍历完了字符串,那么提前回溯
            return;
        }
        if (s.charAt(start) == '0'){//如果当前数字是0,那么这段IP地址只能是0,将当前搜索到的结果赋0之后,直接跳到下一段搜索
            segments[id] = 0;
            dfs(id+1,start+1,s,list,segments);
        }
        int addr = 0;
        for (int i = start; i < s.length(); i++) {
            addr = addr * 10 + (s.charAt(i)-'0');
            if (addr > 0 && addr <= 255){
                segments[id] = addr;
                dfs(id+1,i+1,s,list,segments);
            }else {
                break;
            }
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值