剑指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 二叉树的下一个结点
题目描述
给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回。注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针。
分析:根据中序遍历,下一个节点需要分以下几种情况
- 有右子树,那么下一个是右子树的最左叶子节点
- 无右子树,那么下一个是节点一定在上面,如果当前节点是父节点左子节点,那么下一个就是父节点;如果是父节点的右子节点,那么继续向上寻找,直到是前一种情况或者到达了根节点
/*
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;
}
}