合并K个已排序的链表&&字符串的排列&&接雨水问题

158 阅读1分钟

NC51 合并K个已排序的链表

题目链接

1、解题思路

类似于归并排序的合并过程,这不过这个合并需要用到递归和二分,还有合并两个有序链表。

2、代码
import java.util.*;
/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
public class Solution {
    private ListNode mergeTwoList(ListNode l1, ListNode l2) {
        ListNode dummy = new ListNode(0);
        ListNode tail = dummy;
        while (l1 != null || l2 != null) {
            if (l1 == null) {
                tail.next = l2;
                break;
            } else if (l2 == null) {
                tail.next = l1;
                break;
            } else if (l1.val <= l2.val) {
                ListNode temp = l1.next;
                l1.next = null;
                tail.next = l1;
                tail = tail.next;
                l1 = temp;
            } else {
                ListNode temp = l2.next;
                l2.next = null;
                tail.next = l2;
                tail = tail.next;
                l2 = temp;
            }
        }
        return dummy.next;
    }

    private ListNode mergeKListsHelper(ArrayList<ListNode> lists, int l, int r) {
        if (l == r) {
            return lists.get(l);
        } else {
            int mid = l + (r - l) / 2;
            return mergeTwoList(mergeKListsHelper(lists, l, mid), mergeKListsHelper(lists, mid + 1, r));
        }
    }

    public ListNode mergeKLists(ArrayList<ListNode> lists) {
        if(lists == null || lists.size() == 0){
            return null;
        }
        return mergeKListsHelper(lists, 0, lists.size() - 1);
    }
}

NC121 字符串的排列

题目链接

1、链接

dfs的板子题目,只不过需要去重。题目中的去重可以理解为,先排序,然后假如字符串“aa”,永远让第二个a出现在第一个a的后面。

2、代码
import java.util.*;
public class Solution {
    private void dfs(ArrayList<String> list, char[] chars, int[] vis, StringBuilder stringBuilder) {
        if (stringBuilder.length() == chars.length) {
            list.add(stringBuilder.toString());
        } else {
            for (int i = 0; i < chars.length; i++) {
                if (vis[i] == 1) {
                    continue;
                }
                if (i > 0 && chars[i] == chars[i - 1] && vis[i - 1] == 1) {
                    continue;
                }
                stringBuilder.append(chars[i]);
                vis[i] = 1;
                dfs(list, chars, vis, stringBuilder);
                vis[i] = 0;
                stringBuilder.deleteCharAt(stringBuilder.length() - 1);
            }
        }
    }

    public ArrayList<String> Permutation(String str) {
        char[] chars = str.toCharArray();
        Arrays.sort(chars);
        int[] vis = new int[chars.length];
        ArrayList<String> list = new ArrayList<>();
        StringBuilder stringBuilder = new StringBuilder();
        dfs(list, chars, vis, stringBuilder);
        return list;
    }
}

NC128 接雨水问题

题目链接

1、解题思路

求出左边最高,和右边最高,然后取两者的最小值,表示当前坐标可以存水的最大高度。

2、代码
import java.util.*;


public class Solution {
    /**
     * max water
     * @param arr int整型一维数组 the array
     * @return long长整型
     */
    public long maxWater (int[] arr) {
        // write code here
        // write code here
        long res = 0;
        int[] leftH = new int[arr.length];
        int[] rightH = new int[arr.length];
        leftH[0] = arr[0];
        for (int i = 1; i < arr.length; i++) {
            leftH[i] = leftH[i - 1] > arr[i] ? leftH[i - 1] : arr[i];
        }
        rightH[arr.length - 1] = arr[arr.length - 1];
        for (int i = arr.length - 2; i >= 0; i--) {
            rightH[i] = rightH[i + 1] > arr[i] ? rightH[i + 1] : arr[i];
        }
        for (int i = 0; i < arr.length; i++) {
            res = res + (leftH[i] < rightH[i] ? (leftH[i] - arr[i]) : (rightH[i] - arr[i]));
        }
        return res;
    }
}