兩數之差(鏈表實現)面試算法題——字節跳動


字節跳動客戶端一面遇到的算法題

由於是第一次,面試時有點小緊張,上來就給我整了一道手撕算法,着實有點懵,想了很久都沒有思路....
過了幾天才想着要把這道題解決,實在是懶狗捏

https://www.nowcoder.com/discuss/694139?source_id=profile_create_nctrack&channel=-1

參考題目:兩數之和 https://leetcode-cn.com/problems/add-two-numbers/


package LeetCode.字節跳動面試題.大數之差鏈表版;

import java.util.ArrayList;

/*
   兩個大數之差 鏈表版
   兩個鏈表 分別存放兩個大數,頭部放最高位,尾部放最低位,
   求這兩個數的差
 */
public class Solution {

    public static void main(String[] args) {


        int[] nums1 = {6,9};
        int[] nums2 = {5,5,7};

        int len_1 = nums1.length;
        int len_2 = nums2.length;

        ListNode head1 = addListNode(nums1);
        ListNode head2 = addListNode(nums2);


        if (len_1 > len_2) {  // 大數減小數
            System.out.println(listToArrayList(head1));
            System.out.print("-  ");
            System.out.println(listToArrayList(head2));
            System.out.println(listToArrayList(minusInList(head1, head2)));
        }else {  // 小數減大數
            System.out.println(listToArrayList(head1));
            System.out.print("-  ");
            System.out.println(listToArrayList(head2));
            System.out.println("- " +  listToArrayList(minusInList(head2, head1)));
        }
    }


    public static ListNode minusInList(ListNode head1, ListNode head2) {

        ListNode ans = new ListNode(-1);
        ListNode p = ans; // ans 是頭節點
        int pre = 0; // 表示借位

        // 反轉鏈表 從尾部往前計算每一位的差值
        head1 = reverse(head1);
        head2 = reverse(head2);

        while (head1 != null && head2 != null) {
            int differ = head1.val - head2.val + pre;
            pre = differ < 0 ? -1 : 0;
            if (differ<0) {
                differ = (differ + 10) % 10;
            }
            p.next = new ListNode(differ);
            p = p.next;
            head1 = head1.next;
            head2 = head2.next;
        }


        while (head1 != null) {

            int differ = head1.val+ pre;
            pre = differ < 0 ? -1 : 0;
            if (differ<0) {
                differ = (differ + 10) % 10;
            }
            p.next = new ListNode(differ);
            p = p.next;
            head1 = head1.next;
        }
        while (head2 != null) {

            int differ = head2.val + pre;
            pre = differ < 0 ? -1 : 0;
            if (differ<0) {
                differ = (differ + 10) % 10;
            }
            p.next = new ListNode(differ);
            p = p.next;
            head2 = head2.next;
        }

        // 反轉鏈表
        return reverse(ans.next);

    }


    public static ListNode reverse(ListNode head) { // 實現反轉鏈表
        ListNode pre = null;

        while (head != null) {
            ListNode next = head.next;
            head.next = pre;
            pre = head; // 這里容易寫錯!
            head = next;
        }
        return pre;
    }

    public static ArrayList<Integer> listToArrayList(ListNode head) { // 將鏈表轉化為數組

        ArrayList<Integer> list = new ArrayList<Integer>();

        if (head == null) {
            return list;
        }

        while (head != null) {
            list.add(head.val);
            head = head.next;
        }

        return list;
    }

    public static ListNode addListNode(int[] nums) { // 根據數組來建立鏈表
        ListNode head = new ListNode(-1);
        ListNode temp = null;

        temp = head;

        for (int i = 0; i < nums.length; i++) {

            temp.next = new ListNode(nums[i]);
            temp = temp.next;
/*            System.out.print("nums[" + i + "]: "+nums[i] + " temp.val : ");
            System.out.println(temp.val);*/

        }
        return head.next; // 返回該鏈表的頭節點
    }
}


class ListNode {
    int val;
    ListNode next = null;

    public ListNode(int val) {
        this.val = val;
    }
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM