剑指offer题解12

52 字符流中第一个重复的字符

题目描述
请实现一个函数用来找出字符流中第一个只出现一次的字符。例如,当从字符流中只读出前两个字符"go"时,第一个只出现一次的字符是"g"。当从该字符流中读出前六个字符“google"时,第一个只出现一次的字符是"l"。

输出描述:
如果当前字符流没有存在出现一次的字符,返回#字符。

分析:记录下只出现一次的字符的顺序,动态更改这个顺序即可。使用数组记录是否出现过,使用list记录顺序。

public class Solution {
    //Insert one char from stringstream
    private List<Character> queue = new ArrayList<>();
    private int[] count = new int[256];
    
    public void Insert(char ch) {
        if(count[ch]==0){
            count[ch]=1;
            queue.add(ch);
        }else if (count[ch]==1){
            count[ch]++;
            queue.remove(Character.valueOf(ch));
        }
    }

    //return the first appearence once char in current stringstream
    public char FirstAppearingOnce() {
        if (queue.size()==0){
            return '#';
        }
        return queue.get(0);
    }
}

53 链表中环的入口节点

题目描述
给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null。

分析:使用快慢指针法。


public class Solution {

    public ListNode EntryNodeOfLoop(ListNode pHead)
    {
        if(pHead==null||pHead.next==null||pHead.next.next==null){
            return null;
        }
        ListNode slow=pHead.next,high=pHead.next.next;
        while(true){
            
            slow=slow.next;
            high=high.next.next;
            if(slow==high){
                high=pHead;
                while(slow!=high){
                    slow=slow.next;
                    high=high.next;
                }
                return high;
            }
        }
         
    }
}

54 删除链表中重复的节点

题目描述
在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针。 例如,链表1->2->3->3->4->4->5 处理后为 1->2->5

分析:记住前驱节点,然后遍历判断即可



public class Solution {
   public ListNode deleteDuplication(ListNode pHead) {
            
            ListNode dummy=new ListNode(0);
            dummy.next=pHead;
            ListNode pre = dummy,curr=pHead;
            while (curr!=null&&curr.next!=null){
                int val=curr.val;
                if (val==curr.next.val){
                    while (curr!=null&&curr.val==val){
                        curr=curr.next;
                    }
                    pre.next=curr;
                }else {
                    pre=pre.next;
                    curr=curr.next;
                }
            }
            return dummy.next;
        }
}

55 二叉树的下一个结点

题目描述
给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回。注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针。

分析:根据中序遍历,下一个节点需要分以下几种情况

  1. 有右子树,那么下一个是右子树的最左叶子节点
  2. 无右子树,那么下一个是节点一定在上面,如果当前节点是父节点左子节点,那么下一个就是父节点;如果是父节点的右子节点,那么继续向上寻找,直到是前一种情况或者到达了根节点
/*
public class TreeLinkNode {
    int val;
    TreeLinkNode left = null;
    TreeLinkNode right = null;
    TreeLinkNode next = null;

    TreeLinkNode(int val) {
        this.val = val;
    }
}
*/
public class Solution {
    public TreeLinkNode GetNext(TreeLinkNode pNode)
    {
        if(pNode==null){
            return null;
        }
        //有右子树
        if(pNode.right!=null){
            pNode=pNode.right;
            while(pNode.left!=null){
                pNode=pNode.left;
            }
            return pNode;
        }
        //无右子树
        //如果该节点是父节点的左节点,那么父节点就是下一个节点
        //如果是父节点的右节点,那么一直往上找,直到是父节点的左节点
        while(pNode.next!=null){
            if(pNode.next.left==pNode){
                return pNode.next;
            }
            pNode=pNode.next;
            
        }
        return null;
        
    }
}

猜你喜欢

转载自blog.csdn.net/gentlezuo/article/details/91350925