算法提高之LeetCode刷题Leetcode 答案及解析

Leetcode算法解析51-100

2018-08-18  本文已影响10人  铛铛铛clark

<center>#51 N-Queens</center>

<center>#52 N-Queens II</center>

<center>#53 Maximum Subarray</center>

<center>#55 Jump Game</center>

<center>#58 Length of Last Word</center>

<center>#60 Permutation Sequence</center>

<center>#61 Rotate List</center>

<center>#66 Plus One</center>

<center>#67 Add Binary</center>

<center>#69 Sqrt(x)</center>

<center>#70 Climbing Stairs</center>

<center>#75 Sort Colors</center>

<center>#77 Combinations</center>

<center>#78 Subsets</center>

<center>#79 Word Search</center>

# code block
class Solution {
    public static final int[] dx = {1, 0, 0, -1};
    public static final int[] dy = {0, 1, -1, 0};
    public boolean exist(char[][] board, String word) {
        if (word == null || word.length() == 0) {
            return true;
        }
        if (board == null || board.length == 0 || board[0].length == 0) {
            return false;
        }
        int m = board.length, n = board[0].length;
        char[] wc = word.toCharArray();
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                boolean[][] visited = new boolean[m][n];
                if (board[i][j] != wc[0]) {
                    continue;
                }
                if (dfsHelper(board, wc, visited, i, j, 0)) {
                    return true;
                }
            }
        }
        return false;
    }

    private boolean dfsHelper(char[][] board, char[] wc, boolean[][] visited, int x, int y, int start) {
        if (visited[x][y]) {
            return false;
        }
        if (wc[start] != board[x][y]) {
            return false;
        }
        if (start == wc.length - 1) {
            // find the word
            return true;
        }
        visited[x][y] = true;
        for (int i = 0; i < 4; i++) {
            if (valid(x + dx[i], y + dy[i], board, visited) && dfsHelper(board, wc, visited, x + dx[i], y + dy[i], start + 1)) {
                return true;
            }
        }
        visited[x][y] = false;
        return false;
    }

    private boolean valid(int x, int y, char[][] board, boolean[][] visited) {
        return x >= 0 && x < board.length && y >= 0 && y < board[0].length && !visited[x][y];
    }
}

<center>#80 Remove Duplicates from Sorted Array II</center>

<center>#83 Remove Duplicates from Sorted List</center>

}

* Time Complexity: O(n)
* Space Complexity: O(1)
### <center>#86 Partition List</center>
* [link](https://leetcode.com/problems/partition-list/description/)
* Description:
* Given a linked list and a value x, partition it such that all nodes less than x come before nodes greater than or equal to x.
* You should preserve the original relative order of the nodes in each of the two partitions.
* Input: 1->4->3->2->5->2 and x = 3
* Output: 1->2->2->4->3->5
* Solution:
* 简单链表题,注意使用dummynode和指针赋值的先后问题
* Code:

code block

public ListNode partition(ListNode head, int x) {
ListNode dummy1 = new ListNode(0);
ListNode dummy2 = new ListNode(0);
ListNode curr1 = dummy1;
ListNode curr2 = dummy2;
while (head != null) {
if (head.val < x) {
curr1.next = head;
head = head.next;
curr1 = curr1.next;
curr1.next = null;
} else {
curr2.next = head;
head = head.next;
curr2 = curr2.next;
curr2.next = null;
}
}
curr1.next = dummy2.next;
return dummy1.next;
}

* Time Complexity: O(n)
* Space Complexity: O(1)
### <center>#88 Merge Sorted Array</center>
* [link](https://leetcode.com/problems/merge-sorted-array/description/)
* Description:
* Given two sorted integer arrays nums1 and nums2, merge nums2 into nums1 as one sorted array.
* Input: [4,5,6,0,0,0] 3 [1,2,3] 3
* Output: [1,2,3,4,5,6]
* Assumptions:
* You may assume that nums1 has enough space (size that is greater or equal to m + n) to hold additional elements from nums2. The number of elements initialized in nums1 and nums2 are m and n respectively.

* Solution:
*  用归并排序的merge方法。不适用额外空间的方法就是从尾巴开始归并, 先把大的数填进去
* Code:

code block

public void merge(int[] nums1, int m, int[] nums2, int n) {
int length = m + n;
int ptM = m - 1;
int ptN = n - 1;
int pt = length - 1;
while (pt >= 0) {
if (ptN < 0) {
//nums2 merge complete, nums1 can left as it is
break;
} else if (ptM < 0) {
nums1[pt] = nums2[ptN--];
} else if (nums1[ptM] > nums2[ptN]) {
nums1[pt] = nums1[ptM--];
} else {
nums1[pt] = nums2[ptN--];
}
pt--;
}
}

* Time Complexity: O(n)
* Space Complexity: O(1)
### <center>#90 Subsets II</center>
* [link](https://leetcode.com/problems/subsets-ii/description/)
* Description:
* Given a collection of integers that might contain duplicates, nums, return all possible subsets.
* The solution set must not contain duplicate subsets.
* Input: nums = [1,2,2]
* Output:
[
  [2],
  [1],
  [1,2,2],
  [2,2],
  [1,2],
  []
]
* Solution:
* 先排序,去重, 去重的地方注释了remove duplicate
* 对subsets的隐式图进行遍历,记录下每一个状态
* Code:

code block

public List<List<Integer>> subsetsWithDup(int[] nums) {
List<List<Integer>> subsets = new ArrayList<>();
if (nums == null || nums.length == 0) {
subsets.add(new ArrayList<Integer>());
return subsets;
}
Arrays.sort(nums);
dfsHelper(nums, 0, new ArrayList<Integer>(), subsets);
return subsets;
}

private void dfsHelper(int[] nums, int start, List<Integer> state, List<List<Integer>> subsets) {
subsets.add(new ArrayList<Integer>(state));
for (int i = start; i < nums.length; i++) {
// remove duplicate
if (i != start && nums[i] == nums[i - 1]) {
continue;
}
state.add(nums[i]);
dfsHelper(nums, i + 1, state, subsets);
state.remove(state.size() - 1);
}
}

* Time Complexity: O(n * 2 ^ n)
* Space Complexity: O(n)
上一篇 下一篇

猜你喜欢

热点阅读