0
点赞
收藏
分享

微信扫一扫

day16-算法每日4题

无聊到学习 2022-04-22 阅读 55
算法

43. 字符串相乘

class Solution {
 /**
     * 给定两个以字符串形式表示的非负整数num1和num2,返回num1和num2的乘积,它们的乘积也表示为字符串形式。
     * 注意:不能使用任何内置的 BigInteger 库或直接将输入转换为整数。
     */
    public String multiply(String num1, String num2) {
        if (num1 == null || num1.length() == 0 || num2 == null || num2.length() == 0) return "";
        if (num1.equals("0") || num2.equals("0")) return "0";
        int len1 = num1.length();
        int len2 = num2.length();
        // 存某一列的运算结果
        //
        //          1     2     3     i
        //          4     5     6     j
        //   + --------------------
        //          6    12    18
        //      5   10   15
        //   4  8   12
        //   4  13  28   27    18
        //   ------------------------
        //   5  6   0     8    8

        // 最长是两个数字的长度之和
        int[] ansArr = new int[len1 + len2];
        // 从个位开始
        for (int i = len1 - 1; i >= 0; i--) {
            int x = num1.charAt(i) - '0';
            for (int j = len2 - 1; j >= 0; j--) {
                int y = num2.charAt(j) - '0';
                // 这一列的和存在 i+j+1的索引位置
                ansArr[i + j + 1] += x * y;
            }
        }
        // 统一进位
        for (int i = len1 + len2 - 1; i > 0; i--) {
            // 前面一位
            ansArr[i - 1] += ansArr[i] / 10;
            // 当前位
            ansArr[i] %= 10;
        }
        StringBuilder ans = new StringBuilder();
        // 看最高位有没有填数字
        int idx = ansArr[0] == 0 ? 1 : 0;
        while (idx < len1 + len2) {
            ans.append(ansArr[idx]);
            idx++;
        }
        return ans.toString();
    }
}

912. 排序数组

class Solution {
    public int[] sortArray(int[] nums) {
        quickSort(nums, 0, nums.length - 1);
        return nums;
    }
 /**
     * 快速排序
     * 选取一个数字作为Pivot中心轴,
     * 将大于Pivot的数字放在Pivot的右边
     * 将小于Pivot的数字放在Pivot的左边
     * 分别对左右子序列重复前三步操作
     */
    void quickSort(int[] nums, int L, int R) {
        if (L >= R) return;
        int left = L, right = R;
        // 以最左边的为中心轴
        int pivot = nums[left];
        while (left < right) {
            // 如果right的值比pivot大,right--  此 while 结束时恰好 nums[right] < pivot
            while (left < right && nums[right] >= pivot) right--;
            // 将右边的值赋值到最左边
            if (left < right) nums[left] = nums[right];
            //如果left的值比pivot小,right++  此 while 结束时恰好 nums[left] > pivot
            while (left < right && nums[left] <= pivot) left++;
            // 将左边的值赋值到最右边
            if (left < right) nums[right] = nums[left];
            // 当左右位置重合时,将Pivot赋值到这个重合位置
            if (left >= right) nums[left] = pivot;
        }
        // 重合的位置左右两边继续重复操作
        // 左边
        quickSort(nums, L, right - 1);
        // 右边
        quickSort(nums, right + 1, R);
    }
    
      /**
     * 冒泡排序 会超时
     * 比较相邻的元素,如果第一个比第二个大,就交换
     * 对每一对相邻元素进行同样的操作,从开始的第一队到最后一对,这样最后的元素应该是最大的
     * 然后重复上面的步骤
     */
    void bubbleSort(int[] nums) {
        for (int i = 0; i < nums.length - 1; i++) {
            // 一轮比较n-1次
            for (int j = 0; j < nums.length - 1; j++) {
                // 相邻两个数字进行比较
                if (nums[j] > nums[j + 1]) {
                    swap(nums, j, j + 1);
                }
            }
        }
    }

    void swap(int[] nums, int i, int j) {
        if (nums[i] == nums[j]) return;
        nums[i] = nums[i] ^ nums[j];
        nums[j] = nums[i] ^ nums[j];
        nums[i] = nums[i] ^ nums[j];
    }
}

396. 旋转函数

class Solution {
   /**
     * nums的元素之和为numSum
     * F(0)= 0×nums[0] + 1×nums[1]+…+(n−1)×nums[n−1]
     * F(1)= 1×nums[0] + 2×nums[1] + (n-1)×nums[n−2] +…+ 0 × nums[n−1]=  F(0) + numSum − n × nums[n−1]
     * F(k)= F(k−1) + numSum− n×nums[n−k]
     */
    public int maxRotateFunction(int[] nums) {
        if (nums == null || nums.length == 0) return 0;
        int f = 0, n = nums.length, numSum = Arrays.stream(nums).sum();
        for (int i = 0; i < n; i++) {
            f += i * nums[i];
        }
        int res = f;
        for (int i = n - 1; i > 0; i--) {
            f += numSum - n * nums[i];
            res = Math.max(res, f);
        }
        return res;
    }
}

206. 反转链表

public class Solution {
    /**
     * 递归进行翻转链表
     */
    public ListNode reverseList(ListNode head) {
        // 如果链表只有一个节点的时候反转也是它自己,直接返回即可。
        if (head == null || head.next == null) return head;
        //    1   -> reverse( 2 -> 3 -> 4 -> null)    翻转后 1  -> reverse( 2 <- 3 <- 4)
        //  head                                          head                      last
        // 输入一个节点 head,将「以 head 为起点」的链表反转,并返回反转之后的头结点。
        ListNode last = reverseList(head.next);
        // 含义: last.next -> head
        head.next.next = head;
        head.next = null;
        return last;
    }

    /**
     * 迭代
     * 将链表中每一个节点的 next 引用指向其前驱节点
     */
    public ListNode reverseList2(ListNode head) {
        ListNode prev = null;
        ListNode curr = head;
        while (curr != null) {
            ListNode next = curr.next;
            curr.next = prev;
            prev = curr;
            curr = next;
        }
        return prev;
    }
}

举报

相关推荐

0 条评论