lintcode阶梯训练第六关(九章)

6、合并排序数组

  • 题目
    合并两个排序的整数数组A和B变成一个新的数组。
    样例
    给出A=[1,2,3,4],B=[2,4,5,6],返回 [1,2,2,3,4,4,5,6]

  • 代码

class Solution {
    public int[] mergeSortedArray(int[] A, int[] B) {
        if (A == null || A.length == 0) {
            return B;
        }
        if (B == null || B.length == 0) {
            return A;
        }
        int len = A.length + B.length;
        int[] ans = new int[len];
        int i = 0, j = 0, k = 0;
        while (i < A.length && j < B.length) {
            if (A[i] < B[j]) {
                ans[k++] = A[i++];
            } else {
                ans[k++] = B[j++];
            }
        }
        while (i < A.length) {
            ans[k++] = A[i++];
        }
        while (j < B.length) {
            ans[k++] = B[j++];
        }
        return ans;
    }
}

64、合并排序数组 II

  • 题目
    合并两个排序的整数数组A和B变成一个新的数组。
    注意事项
    你可以假设A具有足够的空间(A数组的大小大于或等于m+n)去添加B中的元素。
    样例
    给出 A = [1, 2, 3, empty, empty], B = [4, 5]
    合并之后 A 将变成 [1,2,3,4,5]

  • 代码

class Solution {
    public void mergeSortedArray(int[] A, int m, int[] B, int n) {
        int i = m - 1, j = n - 1, k = m + n - 1;
        while (i >= 0 && j >= 0) {
            if (A[i] > B[j]) {
                A[k--] = A[i--];
            } else {
                A[k--] = B[j--];
            }
        }
        while (j >= 0) {
            A[k--] = B[j--];
        }
    }
}

604、滑动窗口内数的和

  • 题目
    给你一个大小为n的整型数组和一个大小为k的滑动窗口,将滑动窗口从头移到尾,输出从开始到结束每一个时刻滑动窗口内的数的和。
    样例
    对于数组 [1,2,7,8,5] ,滑动窗口大小k= 3 。
    1 + 2 + 7 = 10
    2 + 7 + 8 = 17
    7 + 8 + 5 = 20
    返回 [10,17,20]

  • 代码

public class Solution {
    public int[] winSum(int[] nums, int k) {
        if (nums == null || nums.length < k || k <= 0) {
            return new int[0];
        }
        int[] ans = new int[nums.length - k + 1];
        for (int i = 0; i < k; i++) {
            ans[0] += nums[i];
        }
        for (int i = 1; i < ans.length; i++) {
            ans[i] = ans[i - 1] - nums[i - 1] + nums[i + k - 1];
        }
        return ans;
    }
}

138、子数组之和

  • 题目
    给定一个整数数组,找到和为零的子数组。你的代码应该返回满足要求的子数组的起始位置和结束位置
    【不熟】
    注意事项
    There is at least one subarray that it’s sum equals to zero.
    样例
    给出 [-3, 1, 2, -3, 4],返回[0, 2] 或者 [1, 3].

  • 代码

public class Solution {
    public ArrayList<Integer> subarraySum(int[] nums) {
        Map<Integer, Integer> map = new HashMap<>();
        map.put(0, -1);
        int sum = 0;
        ArrayList<Integer> ans = new ArrayList<>();
        for (int i = 0; i < nums.length; i++) {
            sum += nums[i];
            if (map.containsKey(sum)) {
                ans.add(map.get(sum) + 1);
                ans.add(i);
                return ans;
            }
            map.put(sum, i);
        }
        return ans;
    }
}

41、最大子数组

  • 题目
    给定一个整数数组,找到一个具有最大和的子数组,返回其最大和。
    【没想到】
    注意事项
    子数组最少包含一个数
    样例
    给出数组[−2,2,−3,4,−1,2,1,−5,3],符合要求的子数组为[4,−1,2,1],其最大和为6

  • 代码

public class Solution {
    public int maxSubArray(int[] nums) {
        if(nums == null || nums.length == 0) {
            return 0;
        }
        int preSum = 0;
        int max = Integer.MIN_VALUE;
        for (int i = 0; i < nums.length; i++) {
            preSum += nums[i];
            max = Math.max(max, preSum);
            preSum = Math.max(preSum, 0);
        }
        return max;
    }
}

139、最接近零的子数组和

  • 题目
    给定一个整数数组,找到一个和最接近于零的子数组。返回第一个和最有一个指数。你的代码应该返回满足要求的子数组的起始位置和结束位置
    样例
    给出[-3, 1, 1, -3, 5],返回[0, 2],[1, 3], [1, 1], [2, 2] 或者 [0, 4]。

  • 代码

class Pair {
    int sum;
    int index;
    public Pair(int sum, int index) {
        this.sum = sum;
        this.index = index;
    }
}
public class Solution {
    public int[] subarraySumClosest(int[] nums) {
        int[] result = new int[2];
        if (nums == null || nums.length == 0) {
            return result;
        }
        int len = nums.length;
        Pair[] preSum = new Pair[len + 1];
        preSum[0] = new Pair(0, -1);        
        for (int i = 1; i < preSum.length; i++) {
            int sum = preSum[i - 1].sum + nums[i - 1];
            preSum[i] = new Pair(sum, i - 1);
        }
        Arrays.sort(preSum, new Comparator<Pair>() {
            public int compare(Pair a, Pair b) {
                return a.sum - b.sum;
            }
        });
        int min = Integer.MAX_VALUE;
        for (int i = 1; i < preSum.length; i++) {
            int diff = preSum[i].sum - preSum[i - 1].sum;
            if (diff < min) {
                result[0] = Math.min(preSum[i].index, preSum[i - 1].index) + 1;
                result[1] = Math.max(preSum[i].index, preSum[i - 1].index);
                min = diff;
            }
        }
        return result;
    }
}

102、带环链表

  • 题目
    给定一个链表,判断它是否有环。
    样例
    给出 -21->10->4->5, tail connects to node index 1,返回 true

  • 代码

public class Solution {
    public boolean hasCycle(ListNode head) {
        if (head == null || head.next == null) {
            return false;
        }
        ListNode slow = head;
        ListNode fast = head.next;
        while (fast != null && fast.next != null) {
            if (slow == fast) {
                return true;
            }
            slow = slow.next;
            fast = fast.next.next;
        }
        return false;
    }
}

105、复制带随机指针的链表

  • 题目
    给出一个链表,每个节点包含一个额外增加的随机指针可以指向链表中的任何节点或空的节点。
    返回一个深拷贝的链表。
    【再来遍吧~】
  • 代码
/**
 * Definition for singly-linked list with a random pointer.
 * class RandomListNode {
 *     int label;
 *     RandomListNode next, random;
 *     RandomListNode(int x) { this.label = x; }
 * };
 */
public class Solution {
    public RandomListNode copyRandomList(RandomListNode head) {
        if (head == null) {
            return head;
        }
        Map<RandomListNode, RandomListNode> map = new HashMap<>();
        RandomListNode dummy = new RandomListNode(0);
        RandomListNode newHead = dummy, newNode;
        while (head != null) {
            if (map.containsKey(head)) {
                newNode = map.get(head);
            } else {
                newNode = new RandomListNode(head.label);
                map.put(head, newNode);
            }
            newHead.next = newNode;
            if (head.random != null) {
                if (map.containsKey(head.random)) {
                    newNode.random = map.get(head.random);
                } else {
                    newNode.random = new RandomListNode(head.random.label);
                    map.put(head.random, newNode.random);
                }
            }
            newHead = newNode;
            head = head.next;
        }
        return dummy.next;
    }
}

599、Insert into a Cyclic Sorted List

  • 题目
    Given a node from a cyclic linked list which has been sorted, write a function to insert a value into the list such that it remains a cyclic sorted list. The given node can be any single node in the list. Return the inserted new node.
    【想太多】
    注意事项
    3->5->1 is a cyclic list, so 3 is next node of 1.
    3->5->1 is same with 5->1->3
    样例
    Given a list, and insert a value 4:
    3->5->1
    Return 5->1->3->4

  • 代码

public class Solution {
    public ListNode insert(ListNode node, int x) {
        if (node == null) {
            node = new ListNode(x);
            node.next = node;
            return node;
        }
        ListNode pre = node;
        ListNode p = node.next;
        while (p != node) {
            if (pre.val <= x && x <= p.val) {
                break;
            }
            if (pre.val > p.val && (pre.val <= x || x <= p.val)) {
                break;
            }
            pre = p;
            p = p.next;
        }
        ListNode newNode = new ListNode(x);
        pre.next = newNode;
        newNode.next = p;
        return newNode;
    }
}

165、合并两个排序链表

  • 题目
    将两个排序链表合并为一个新的排序链表
    样例
    给出 1->3->8->11->15->null,2->null, 返回 1->2->3->8->11->15->null。

  • 代码

public class Solution {
    public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
        ListNode dummy = new ListNode(0);
        ListNode node = dummy;
        while (l1 != null && l2 != null) {
            if (l1.val < l2.val) {
                node.next = l1;
                l1 = l1.next;
            } else {
                node.next = l2;
                l2 = l2.next;
            }
            node = node.next;
        }
        if (l1 != null) {
            node.next = l1;
        }
        if (l2 != null) {
            node.next = l2;
        }
        return dummy.next;
    }
}

98、链表排序

  • 题目
    在 O(n log n) 时间复杂度和常数级的空间复杂度下给链表排序。
    【没想到~】
    样例
    给出 1->3->2->null,给它排序变成 1->2->3->null.

  • 代码

public class Solution {
    public ListNode sortList(ListNode head) {
        if (head == null || head.next == null) {
            return head;
        }
        ListNode mid = getMid(head);
        ListNode right = sortList(mid.next);
        mid.next = null;
        ListNode left = sortList(head);
        return merge(left, right);
    }
    private ListNode getMid(ListNode head) {
        ListNode slow = head;
        ListNode fast = head.next;
        while (fast != null && fast.next != null) {
            slow = slow.next;
            fast = fast.next.next;
        }
        return slow;
    }
    private ListNode merge(ListNode left, ListNode right) {
        ListNode dummy = new ListNode(0);
        ListNode head = dummy;
        while (left != null && right != null) {
            if (left.val < right.val) {
                head.next = left;
                left = left.next;
            } else {
                head.next = right;
                right = right.next;
            }
            head = head.next;
        }
        if (left != null) {
            head.next = left;
        } else {
            head.next = right;
        }
        return dummy.next;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值