剑指offer篇

2019-11-04  本文已影响0人  后来丶_a24d

两个栈实现队列

public class Solution {
    Stack<Integer> stack1 = new Stack<Integer>();
    Stack<Integer> stack2 = new Stack<Integer>();
    
    public void push(int node) {
        stack1.push(node);
    }

    public int pop() {
        if(stack2.empty()) {
            while (!stack1.empty()){
                stack2.push(stack1.pop());
            }
        }
        return  stack2.pop();
    }
}

包含min的栈

public class Solution {

   Stack<Integer> dataStack = new Stack<Integer>();
    Stack<Integer> minStack = new Stack<Integer>();

    public void push(int node) {
        dataStack.push(node);
        if(minStack.isEmpty() || node < minStack.peek()){
            minStack.push(node);
        }
        else{
            minStack.push(minStack.peek());
        }
    }

    public void pop() {
        dataStack.pop();
        minStack.pop();
    }

    public int top() {
        return dataStack.peek();
    }

    public int min() {
        return minStack.peek();
    }
}

栈压入弹出顺序

public class Solution {
    public boolean IsPopOrder(int [] pushA,int [] popA) {
        if(pushA.length == 0 || pushA.length != popA.length){
            return false;
        }
     
        Stack<Integer> stack = new Stack<>();
        int popAIndex = 0;
        for(int i = 0; i < pushA.length; i++){
            stack.push(pushA[i]);
            while(!stack.isEmpty() && stack.peek() == popA[popAIndex]){
                stack.pop();
                popAIndex++;
            }
        }
        return stack.isEmpty();
    }
}


链表

从尾到头打印链表

 public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
          if(listNode == null){
            return new ArrayList<>();
        }
        ArrayList<Integer> list = new ArrayList<>();
        while(listNode != null){
            list.add(listNode.val);
            listNode = listNode.next;
        }
        Collections.reverse(list);
        return list;
    }

链表中倒数第k个节点

  public ListNode FindKthToTail(ListNode head,int k) {
        if(k < 0){
            return null;
        }
        ListNode pre = head;
        ListNode now = head;
        int kTemp = k;
        int listNodeLength = 0;
        while(now != null){
            listNodeLength++;
            now = now.next;
            if(k < 1){
                pre = pre.next;
            }
            k--;
        }
        if(listNodeLength < kTemp){
            return null;
        }
        return pre;
    }

反转链表

 public ListNode ReverseList(ListNode head) {
        if(head == null){
            return null;
        }
        ListNode pre = null;
        ListNode next = null;
        while(head != null){
            next = head.next;
            head.next = pre;
            pre = head;
            head = next;
        }
        return pre;
    }

合并两个排序的链表

public ListNode Merge(ListNode list1,ListNode list2) {
        if(list1 == null){
            return list2;
        }
        if(list2 == null){
            return list1;
        }
        ListNode head;
        if(list1.val > list2.val){
            head = new ListNode(list2.val);
            list2 = list2.next;
        }else{
            head = new ListNode(list1.val);
            list1 = list1.next;
        }
        ListNode temp = head;
        while(list1 != null && list2 != null){
            ListNode next;
             if(list1.val > list2.val){
                next = new ListNode(list2.val);
                list2 = list2.next;
            }else{
                next = new ListNode(list1.val);
                list1 = list1.next;
            }
            head.next = next;
            head = head.next;
        }
        while(list1 != null){
            ListNode next = new ListNode(list1.val);
            list1 = list1.next;
            head.next = next;
            head = head.next;
        }
        while(list2 != null){
            ListNode next = new ListNode(list2.val);
            list2 = list2.next;
            head.next = next;
            head = head.next;
        }
        return temp;
    }

复杂链表复制

/*
  1、复制每个节点,如:复制节点A得到A1,将A1插入节点A后面 
  2、遍历链表,A1->random = A->random->next;`
  3、将链表拆分成原链表和复制后的链表`
*/
 public RandomListNode Clone(RandomListNode pHead) {
        if(pHead == null) {
            return null;
        }
         
        RandomListNode currentNode = pHead;
        //1、复制每个结点,如复制结点A得到A1,将结点A1插到结点A后面;
        while(currentNode != null){
            RandomListNode cloneNode = new RandomListNode(currentNode.label);
            RandomListNode nextNode = currentNode.next;
            currentNode.next = cloneNode;
            cloneNode.next = nextNode;
            currentNode = nextNode;
        }
         
        currentNode = pHead;
        //2、重新遍历链表,复制老结点的随机指针给新结点,如A1.random = A.random.next;
        while(currentNode != null) {
            currentNode.next.random = currentNode.random==null?null:currentNode.random.next;
            currentNode = currentNode.next.next;
        }
         
        //3、拆分链表,将链表拆分为原链表和复制后的链表
        currentNode = pHead;
        RandomListNode pCloneHead = pHead.next;
        while(currentNode != null) {
            RandomListNode cloneNode = currentNode.next;
            currentNode.next = cloneNode.next;
            cloneNode.next = cloneNode.next==null?null:cloneNode.next.next;
            currentNode = currentNode.next;
        }
         
        return pCloneHead;
    }

二叉搜索树与双向链表


//直接用中序遍历
public class Solution {
    TreeNode head = null;
    TreeNode realHead = null;
    public TreeNode Convert(TreeNode pRootOfTree) {
        ConvertSub(pRootOfTree);
        return realHead;
    }
     
    private void ConvertSub(TreeNode pRootOfTree) {
        if(pRootOfTree==null) return;
        ConvertSub(pRootOfTree.left);
        //当左子树为空时,左右都赋值根节点
        if (head == null) {
            head = pRootOfTree;
            realHead = pRootOfTree;
        } else {
            //pRootOfTree 根节点右子树
            head.right = pRootOfTree;
            pRootOfTree.left = head;
            head = pRootOfTree;
        }
        ConvertSub(pRootOfTree.right);
    }
}

两个链表的第一个公共节点

public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) {
        ListNode p1 = pHead1;
        ListNode p2 = pHead2;
        int count_p1 = 0,count_p2 = 0;
        while(p1 != null){
            count_p1++;
            p1=p1.next;
        }
        while(p2 != null){
            count_p2++;
            p2=p2.next;
        }
        if (count_p1 > count_p2) {
            int length = count_p1 - count_p2;
            while(length != 0){
                pHead1=pHead1.next;
                length--;
            }
        }else{
            int length = count_p2 - count_p1;
            while(length != 0){
                pHead2=pHead2.next;
                length--;
            }
        }
        while(pHead1 != null && pHead2 != null && pHead1 != pHead2){
            pHead1 = pHead1.next;
            pHead2= pHead2.next;
        }
        return  pHead1;
    }

求链表中环入口

/**
使用两个指针,一个快指针,一个慢指针,快指针一次走两步,慢指针一次走一步;
若快指针最后变为空,则单链表为无环单链表,返回空指针;
若快慢指针在某一时刻指向同一节点,即二者完全一样,则为有环单链表,
此时让快指针重新指向链表头结点,然后快慢指针均一次走一步,
当快慢指针再次相同时,则此节点即为链表入环节点,将其返回。

**/
 public ListNode EntryNodeOfLoop(ListNode pHead){
        if(pHead == null || pHead.next == null) return null;
        ListNode l1 = pHead;
        ListNode l2 = pHead;
        while(l2 != null && l2.next != null){
            l1 = l1.next;
            l2 = l2.next.next;
            if(l1 == l2){
                l2 = pHead;
                while(l1 != l2){
                    l1 = l1.next;
                    l2 = l2.next;
                }
                if(l1 == l2)    return l2;
            }
            
        }
        return null;
    }

删除重复节点

 //temp为头结点的前一个节点,当当前于下一个节点不重复时,temp节点往下,当前节点往下
//当重复时一直到不重复的地方temp节点next指向它。
public ListNode deleteDuplication(ListNode pHead) {
        if (pHead == null) return null;
        ListNode pHeadTemp = pHead;
        ListNode temp = new ListNode(-1);
        temp.next = pHead;
        ListNode tempPhead = temp;
        while(pHeadTemp!=null && pHeadTemp.next != null){
            if(pHeadTemp.val == pHeadTemp.next.val){
                int val = pHeadTemp.val;
                while(pHeadTemp != null && pHeadTemp.val == val){
                    pHeadTemp = pHeadTemp.next;
                }
                tempPhead.next = pHeadTemp;
            }else{
                tempPhead = pHeadTemp;
                pHeadTemp = pHeadTemp.next;
            }
        }
        return temp.next;
    }

两个有环链表求交点??? todo


上一篇 下一篇

猜你喜欢

热点阅读