美文网首页
Java算法

Java算法

作者: 阿木Robert | 来源:发表于2021-12-20 19:29 被阅读0次

    描述:大数加法

    思路:减字符0,得到数值,两数想加,取余,取进位。

        public String solve(String s, String t) {

            StringBuilder stringBuilder = new StringBuilder();

            int i = s.length() - 1, j = t.length() - 1, carry = 0;

            while (i >= 0 || j >= 0 || carry != 0) {

                int x = i < 0 ? 0 : s.charAt(i--) - '0';

                int y = j < 0 ? 0 : t.charAt(j--) - '0';

                int sum = x + y + carry;

                stringBuilder.append(sum % 10);//添加到字符串尾部

                carry = sum / 10;

            }

            return stringBuilder.reverse().toString();//对字符串反转

        }

    描述:重建链表

    思路:1.快慢指针找到链表中点;2.反转后半段链表;3.前后链表合并。

    public class Solution {

        public void reorderList(ListNode head) {

            if (head == null || head.next == null || head.next.next == null) {

            return;

        }

        //找中点,链表分成两个

        ListNode slow = head;

        ListNode fast = head;

        while (fast.next != null && fast.next.next != null) {

            slow = slow.next;

            fast = fast.next.next;

        }

        ListNode newHead = slow.next;

        slow.next = null;

       

        //第二个链表倒置,反转后半部分链表

        newHead = reverseList(newHead);

       

        //链表节点依次连接

        while (newHead != null) {

            ListNode temp = newHead.next;

            newHead.next = head.next;

            head.next = newHead;

            head = newHead.next;

            newHead = temp;

        }

    }

        private ListNode reverseList(ListNode head) {

            if (head == null) {

                return null;

            }

            ListNode tail = head;

            head = head.next;

            tail.next = null;

            while (head != null) {

                ListNode temp = head.next;

                head.next = tail;

                tail = head;

                head = temp;

            }

            return tail;

        }

    }

    描述:快慢指针找链表环入口节点

    public ListNode EntryNodeOfLoop(ListNode pHead) {

            if(pHead == null) return null;

            // 定义快慢指针

            ListNode slow = pHead;

            ListNode fast = pHead;

            while(fast != null && fast.next != null){

                // 快指针是满指针的两倍速度

                fast = fast.next.next;

                slow = slow.next;

                // 记录快慢指针第一次相遇的结点

                if(slow == fast) break;

            }

            // 若是快指针指向null,则不存在环

            if(fast == null || fast.next == null) return null;

            // 重新指向链表头部

            fast = pHead;

            // 与第一次相遇的结点相同速度出发,相遇结点为入口结点

            while(fast != slow){

                fast = fast.next;

                slow = slow.next;

            }

            return fast;

        }

    描述:判断链表是否有环

    思路:快慢指针

    public boolean hasCycle(ListNode head) {

            if(head == null) return false;

            // 定义快慢指针

            ListNode slow = head;

            ListNode fast = head;

            while(fast != null && fast.next != null){

                // 快指针是满指针的两倍速度

                fast = fast.next.next;

                slow = slow.next;

                // 记录快慢指针第一次相遇的结点

                if(slow == fast) return true;

            }

            return false;

        }

    描述:二叉树根节点到叶子节点的所有路径和

    思路:DFS

        public int sumNumbers(TreeNode root) {

            //如果根节点是空,直接返回0即可

            if (root == null)

                return 0;

            //两个栈,一个存储的是节点,一个存储的是节点对应的值

            Stack<TreeNode> nodeStack = new Stack<>();

            Stack<Integer> valueStack = new Stack<>();

            //全局的,统计所有路径的和

            int res = 0;

            nodeStack.add(root);

            valueStack.add(root.val);

            while (!nodeStack.isEmpty()) {

                //当前节点和当前节点的值同时出栈

                TreeNode node = nodeStack.pop();

                int value = valueStack.pop();

                if (node.left == null && node.right == null) {

                    //如果当前节点是叶子结点,说明找到了一条路径,把这条

                    //路径的值加入到全局变量res中

                    res += value;

                } else {

                    //如果不是叶子节点就执行下面的操作

                    if (node.right != null) {

                        //把子节点和子节点的值分别加入到栈中,这里子节点的值

                        //就是父节点的值*10+当前节点的值

                        nodeStack.push(node.right);

                        valueStack.push(value * 10 + node.right.val);

                    }

                    if (node.left != null) {

                        nodeStack.push(node.left);

                        valueStack.push(value * 10 + node.left.val);

                    }

                }

            }

            return res;

        }

    题目描述

    给出一个升序排序的数组,将其转化为平衡二叉搜索树(BST)

    思路:题目中所给的是一个升序排序的数组,所以一个大体流程就是根据一个中序遍历的序列,还原出一个它对应的二叉树。因为是中序遍历的结果,所以元素的左边都是以该元素为根节点的左子树上的元素,元素的右边都是以该元素为根节点的右子树上的元素。

    又因为是平衡的,所以先找出序列的中点,以中点的值生成根节点,他的左边右边相差不差过一个元素,即它的左子树和右子树的元素个数相差不超过一个,每次都安一样的策略来找根节点,即左右子树的高度相差不会超过1。

    public class Solution {

        /**

        *

        * @param num int整型一维数组

        * @return TreeNode类

        */

        public TreeNode sortedArrayToBST (int[] nums) {

            // 判断特殊情况, 数组为空,或数组上没有元素,直接返回 null

            if (nums == null || nums.length == 0) {

                return null;

            }

            return process(nums, 0, nums.length - 1);

        }

        /**

        *

        * @param nums  整个的有序数组

        * @param left  数组的左边界, 闭区间

        * @param right 数组的右边界, 闭区间

        * @return nums[left ... right] 这个范围的数组,转成 BST 后的根节点

        */

        public TreeNode process(int[] nums, int left, int right) {

            // 左边界 比 右边界 大, 说明数组上没有元素,直接返回 null

            if (left > right) {

                return null;

            }

            // 如果只有一个元素,就把它当成根节点直接返回

            if (left == right) {

                TreeNode root = new TreeNode(nums[left]);

                return root;

            }

            // nums[left ... right] 这个数组的长度

            int len = right - left + 1;

            // nums[left ... right] 这个数组的中点下标,这个下标里的元素值就是 BST 的根节点的值

            int mid = left + len / 2;

            TreeNode root = new TreeNode(nums[mid]);

            // 找出根节点的左子树: 继续递归用这个方法,找出左子树上这个局部范围的BST的根节点

            root.left = process(nums, left, mid - 1);

            // 找出根节点的右子树: 继续递归用这个方法,找出右子树上这个局部范围的BST的根节点

            root.right = process(nums, mid + 1, right);

            return root;

        }

    }

    题目描述

    请实现一个函数,用来判断一棵二叉树是不是对称的。注意,如果一个二叉树同此二叉树的镜像是同样的,定义其为对称的。

    思路:

    因为要比较左右结点是否对称,因此可以通过BFS每次对一层的结点进行遍历并比较是否对称。

    public class Solution {

        boolean isSymmetrical(TreeNode pRoot)

        {

            if(pRoot == null){

                return true;

            }

            // 递归调用

            return recur(pRoot.left, pRoot.right);

        }

        // 递归函数功能:判断左右两个结点是否对称相等

        private boolean recur(TreeNode left, TreeNode right) {

            // 没有子节点,说明当前结点是叶子结点

            if(left == null) {

                return right == null;

            }

            // 没有右子节点

            if(right == null) {

                return false;

            }

            // 左右结点不对称

            if(left.val != right.val) {

                return false;

            }

            // 左子树的右子树和右子树的左子树相同即可

            return recur(left.right, right.left) && recur(left.left, right.right);

        }

    }

    相关文章

      网友评论

          本文标题:Java算法

          本文链接:https://www.haomeiwen.com/subject/uhizfrtx.html