Notes5剑指offer_21-40题

Posted 码农编程录

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Notes5剑指offer_21-40题相关的知识,希望对你有一定的参考价值。


21.调整数组顺序使奇数位于偶数前面

class Solution {
    public int[] exchange(int[] nums) {
        int left = 0;
        int right = nums.length - 1;
        while(left < right)
        {
            //从左往右找偶数 找到偶数 停止
            while(left < right && nums[left] % 2 == 1) left ++;
            //从右往左找奇数 找到奇数停止
            while(left < right && nums[right] % 2 == 0) right --;
            if(left < right)
            {
                int temp = nums[left];
                nums[left] = nums[right];
                nums[right] = temp;
            }
        }
        return nums;
    }
}

22.链表中倒数第k个节点

class Solution {
    public ListNode getKthFromEnd(ListNode head, int k) {
        //单个指针 走到头  len 
        //从头走 len - k
        
        //双指针
        ListNode first = head;
        ListNode second = head;
        for(int i = 0; i < k; i ++)
        {
            //k 大于链表长度
            if(first == null) return null;
            first = first.next;
        }
        while(first != null)
        {
            first = first.next;
            second = second.next;
        }
        return second;
    }
}

23.链表中环的入口结点

class Solution {
    public ListNode entryNodeOfLoop(ListNode head) {
        /*
        //hash表 从头到尾遍历  
        Set<ListNode> hash = new HashSet<>();
        
        while(head != null)
        {
            if(!hash.add(head))
                return head;
            head = head.next;
        }
        
        return null;
        */
        //快慢指针
        ListNode slow = head;//走一步
        ListNode fast = head;//走两步
        while(fast != null)
        {
            slow = slow.next;
            fast = fast.next.next;
            if(fast == slow)
            {
                slow = head;
                while(slow != fast)
                {
                    slow = slow.next;
                    fast = fast.next;
                }
                return slow;
            }
            
        }        
        return null;
    }
}

24.反转链表

class Solution {
    public ListNode reverseList(ListNode head) {
        ListNode pre = null;
        ListNode cur = head;
        while(cur != null)
        {
            //让cur指向 pre
            //然后 pre  cur 都往后走一个
            ListNode temp = cur.next;
            cur.next = pre;
            pre = cur;
            cur = temp;
        }
        return pre;
    }
}

25.合并两个排序的链表

class Solution {
    public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
        //归并排序思想
        ListNode dummy = new ListNode(0);
        ListNode cur = dummy;
        while(l1 != null && l2 != null)
        {
            if(l1.val <= l2.val)
            {
                cur.next = l1;
                l1 = l1.next;
                cur = cur.next;
            }
            else
            {
                cur.next = l2;
                l2 = l2.next;
                cur = cur.next;
            }
        }
        if(l1 != null)
        {
            cur.next = l1;
        }
        if(l2 != null)
        {
            cur.next = l2;
        }
        return dummy.next;
    }
}

26.树的子结构

class Solution {
    public boolean isSubStructure(TreeNode A, TreeNode B) {
        //递归
        //A根 B根
        //A左子树 B
        //A右子树 B
        if(A == null  || B == null) return false;
        return (issubtree(A, B) || isSubStructure(A.left, B)|| isSubStructure(A.right, B));
    }
    public boolean issubtree(TreeNode A, TreeNode B) {
        //true 
        if(B == null) return true;
        //false 
        if(A == null || A.val != B.val) return false;
        return issubtree(A.left, B.left) && issubtree(A.right, B.right);
    }
}

27.二叉树的镜像

class Solution {
    public TreeNode mirrorTree(TreeNode root) {
        //左右子树交换
        if(root == null) return null;
        TreeNode temp = root.left;
        root.left = mirrorTree(root.right);
        root.right = mirrorTree(temp);
        return root;
    }
}

28.对称的二叉树

class Solution {
    public boolean isSymmetric(TreeNode root) {
        if(root == null) return true;
        return dfs(root.left, root.right);
    }
    public boolean dfs(TreeNode left, TreeNode right)
    {
        if(left == null && right == null) return true;
        if(left == null || right ==  null || left.val != right.val) return false;
        return dfs(left.left, right.right) && dfs(left.right, right.left);
    }
}

29.顺时针打印矩阵

class Solution {
    public int[] spiralOrder(int[][] matrix) {
        //判断边界 
        if(matrix.length == 0)
            return new int[0];
        //右下左上
        int left = 0, right = matrix[0].length -1, up = 0, down = matrix.length - 1;
        int num = 0;
        int[] res = new int[(right + 1) * (down + 1)];
        while(true)
        {
            //右
            for(int i = left; i <= right; i ++)
                res[num ++] = matrix[up][i];
            if(++ up > down) break;
            //下
            for(int i = up; i <= down; i ++)
                res[num ++] = matrix[i][right];
            if(-- right < left ) break;
            //左
            for(int i = right; i >= left; i --)
                res[num ++] = matrix[down][i];
            if(-- down < up) break; 
            //上
            for(int i = down; i >= up; i --)
                res[num ++] = matrix[i][left];
            
            if(++ left > right) break;
        }
        return res;
    }
}

30.包含min函数的栈

class MinStack {
    Stack<Integer> A, B;//A正常的栈  B记录最小元素的栈
    /** initialize your data structure here. */
    public MinStack() {
        A = new Stack<>();
        B = new Stack<>();
    }
    
    public void push(int x) {
        //判断当前元素 和栈内最小的元素 对比
        A.add(x);
        if(B.empty() || B.peek() >= x)
            B.add(x);
    }
    
    public void pop() {
        //栈顶元素 是不是 最小的
        //if(A.pop().equals(B.peek()))
        //    B.pop();
        if(A.peek().equals(B.peek()))//不能用 == 必须用 equals
            B.pop();
        
        A.pop();
    }
    
    public int top() {
        //直接写
        return A.peek();
    }
    
    public int min() {
        //找到栈内最小的元素 直接写
        return B.peek();
    }
}

31.栈的压入、弹出序列

class Solution {
    public boolean validateStackSequences(int[] pushed, int[] popped) {
        Stack<Integer> temp = new Stack<>();
        int i = 0;
        for(int num : pushed)
        {
            temp.push(num);//入栈
            //模拟出栈
            while(!temp.isEmpty() && temp.peek() == popped[i])
            {
                temp.pop();
                i ++;
            }
        }
        return temp.isEmpty();
    }
}

32.从上到下打印二叉树

class Solution {
    public int[] levelOrder(TreeNode root) {
        if(root == null) return new int[0];

        ArrayList<Integer> ans = new ArrayList<>();
        //队列操作  保存根节点
        Queue<TreeNode> q = new LinkedList<>();
        q.add(root);
        while(!q.isEmpty())
        {
            //根结点
            TreeNode r = q.poll();
            ans.add(r.val);
            //左子树
            if(r.left != null) q.add(r.left);
            //右子树
            if(r.right != null) q.add(r.right);
        }
        int[] res = new int[ans.size()];
        for(int i = 0; i < ans.size(); i ++)
            res[i] = ans.get(i);
        return res;
    }
}

33.二叉搜索树的后序遍历序列

class Solution {
    public boolean verifyPostorder(int[] postorder) {
        //左<根<右 二叉检索树
        //后序遍历 
        //左右根
        //递归
        return dfs(postorder, 0, postorder.length - 1);
    }
    public boolean dfs(int[] arr, int l, int r)
    {
        if(l >= r) return true;//遍历到最后 都是true
        //r对应 当前子树 根节点
        //找到左右子树的临界点
        int p = l;
        while(arr[p] < arr[r]) p ++;
        int m = p;
        while(arr[p] > arr[r]) p ++;
        return (p == r) && dfs(arr, l, m - 1) && dfs(arr, m, r - 1);
    }
}

34.二叉树中和为某一值的路径


class Solution {
    //前序遍历 根左右
    LinkedList<List<Integer>>  res = new LinkedList<>();//所有路径
    LinkedList<Integer> path = new LinkedList<>();//单条路径
    public List<List<Integer>> pathSum(TreeNode root, int sum) {
        //递归函数
        recur(root, sum);
        return res;
    }
    void recur(TreeNode root, int target){
        //找到 target = 0时候的叶节点
        if(root == null) return;
        path.add(root.val);
        target -= root.val;
        if(target == 0 &&

以上是关于Notes5剑指offer_21-40题的主要内容,如果未能解决你的问题,请参考以下文章

python-剑指offer21-40

剑指offer 面试27题

剑指offer 面试26题

剑指offer 面试32题

剑指offer 面试25题

剑指offer 面试28题