2019年11月13日 星期三

Last Position of Target


Last Position of Target

  • Lintcode : 458 / Leetcode : 34
  • Level : Easy

Problem

Find the last position of a target number in a sorted array. Return -1 if target does not exist.

Example
Example 1:

Input: nums = [1,2,2,4,5,5], target = 2
Output: 2
Example 2:

Input: nums = [1,2,2,4,5,5], target = 6
Output: -1

Concept & Algorithm

Time Complexity & Space Complexity

time : O(logn)
space: O(1)

Answer

class Solution {
public:
    int lastPosition(vector<int> &nums, int target) {
        if (nums.size() == 0) return -1;
        int l = 0, r = nums.size() - 1;
        while (l + 1 < r) {
            int mid = l + (r - l) / 2;
            if (nums[mid] <= target) {
                l = mid;
            }else {
                r = mid;
            }
        }
        if (nums[r] == target) return r;
        if (nums[l] == target) return l;
        return -1;
    }
};
tags: Binary Search

Maximum Number in Mountain Sequence


Maximum Number in Mountain Sequence

  • Lintcode : 585 / Leetcode :
  • Level : Medium

Problem

Given a mountain sequence of n integers which increase firstly and then decrease, find the mountain top.

Example
Example 1:

Input: nums = [1, 2, 4, 8, 6, 3] 
Output: 8
Example 2:

Input: nums = [10, 9, 8, 7], 
Output: 10
Notice
Arrays are strictly incremented, strictly decreasing

Concept & Algorithm

Time Complexity & Space Complexity

time : O(logn)
space: O(1)

Answer

class Solution {
public:
    int mountainSequence(vector<int> &nums) {
        // corner case : if nums.size() == 0
        int l = 0, r = nums.size() - 1;
        while (l + 1 < r) {
            int mid = l + (r - l) / 2;
            if (nums[mid] > nums[mid + 1]) {
                r = mid;
            }else {
                l = mid;
            }
        }
        if (nums[l] > nums[r]) return nums[l];
        return nums[r];
    }
};
tags: Binary Search

Find K Closest Elements


Find K Closest Elements

  • Lintcode : 460 / Leetcode : 658
  • Level : Medium

Problem

Given target, a non-negative integer k and an integer array A sorted in ascending order, find the k closest numbers to target in A, sorted in ascending order by the difference between the number and target. Otherwise, sorted in ascending order by number if the difference is same.

Example
Example 1:

Input: A = [1, 2, 3], target = 2, k = 3
Output: [2, 1, 3]
Example 2:

Input: A = [1, 4, 6, 8], target = 3, k = 3
Output: [4, 1, 6]
Challenge
O(logn + k) time

Notice
The value k is a non-negative integer and will always be smaller than the length of the sorted array.
Length of the given array is positive and will not exceed 10^410
​4
​​ 
Absolute value of elements in the array will not exceed 10^410
​4
​​

Concept & Algorithm

Time Complexity & Space Complexity

time : O(logn + k)
space: O(k)

Answer

class Solution {
public:
    vector<int> kClosestNumbers(vector<int> &A, int target, int k) {
        // corner case
        if (A.size() < k) return A;

        int index = findLastLessAndEqual(A, target);
        vector<int> ans;
        countK(A, target, k, ans, index);
        return ans;
    }
    int findLastLessAndEqual (vector<int> &A, int target) {
        int l = 0, r = A.size() - 1;
        while (l + 1 < r) {
            int mid = l + (r - l) / 2;
            if (A[mid] <= target) {
                l = mid;
            }else {
                r = mid;
            }
        }
        if (A[r] <= target) return r;
        if (A[l] <= target) return l;
        return -1;
    }
    void countK(vector<int> &A, int target, int k, vector<int> &ans, int index) {
        int left = index, right = index + 1;
        while (k && left >= 0 && right < A.size()) {
            while (k && left >= 0 && right < A.size() && abs(A[left] - target) <= abs(A[right] - target)) {
                ans.push_back(A[left--]);
                k--;
            }
            while (k && left >= 0 && right < A.size() && abs(A[left] - target) > abs(A[right] - target)) {
                ans.push_back(A[right++]);
                k--;
            }
        }
        while (k && left >= 0) {
            ans.push_back(A[left--]);
            k--;
        }
        while (k && right < A.size()) {
            ans.push_back(A[right++]);
            k--;
        }
    }
};
tags: Binary Search

Search in a Big Sorted Array


Search in a Big Sorted Array

  • Lintcode : 447 / Leetcode :
  • Level : Medium

Problem

Given a big sorted array with non-negative integers sorted by non-decreasing order. The array is so big so that you can not get the length of the whole array directly, and you can only access the kth number by ArrayReader.get(k) (or ArrayReader->get(k) for C++).

Find the first index of a target number. Your algorithm should be in O(log k), where k is the first index of the target number.

Return -1, if the number doesn't exist in the array.

Example
Example 1:

Input: [1, 3, 6, 9, 21, ...], target = 3
Output: 1
Example 2:

Input: [1, 3, 6, 9, 21, ...], target = 4
Output: -1
Challenge
O(logn) time, n is the first index of the given target number.

Notice
If you accessed an inaccessible index (outside of the array), ArrayReader.get will return 2,147,483,647.

Concept & Algorithm

Time Complexity & Space Complexity

time : O(logn)
space: O(1)

Answer

/**
 * Definition of ArrayReader:
 * 
 * class ArrayReader {
 * public:
 *     int get(int index) {
 *          // return the number on given index, 
 *          // return 2147483647 if the index is invalid.
 *     }
 * };
 */
class Solution {
public:
    int searchBigSortedArray(ArrayReader * reader, int target) {
        int l = 0, r = 1;
        while (reader -> get(r) < target) {
            r *= 2;
        }
        while (l + 1 < r) {
            int mid = l + (r - l) / 2;
            if (reader -> get(mid) >= target) {
                r = mid;
            }
            else {
                l = mid;
            }
        }
        if (reader -> get(l) == target) return l;
        if (reader -> get(r) == target) return r;
        return -1;
    }
};
tags: Binary Search

Alien Dictionary


Alien Dictionary

  • Lintcode : 892 / Leetcode : 269
  • Level : Hard

Problem

There is a new alien language which uses the latin alphabet. However, the order among letters are unknown to you. You receive a list of non-empty words from the dictionary, where words are sorted lexicographically by the rules of this new language. Derive the order of letters in this language.

Example
Example 1:

Input:["wrt","wrf","er","ett","rftt"]
Output:"wertf"
Explanation:
from "wrt"and"wrf" ,we can get 't'<'f'
from "wrt"and"er" ,we can get 'w'<'e'
from "er"and"ett" ,we can get 'r'<'t'
from "ett"and"rftt" ,we can get 'e'<'r'
So return "wertf"

Example 2:

Input:["z","x"]
Output:"zx"
Explanation:
from "z" and "x",we can get 'z' < 'x'
So return "zx"
Notice
You may assume all letters are in lowercase.
You may assume that if a is a prefix of b, then a must appear before b in the given dictionary.
If the order is invalid, return an empty string.
There may be multiple valid order of letters, return the smallest in normal lexicographical order

Concept & Algorithm

Time Complexity & Space Complexity

time : O(string numbers * the index of avg different char position)
space: O(n)

Answer

/*
1. 利用suc存某字符的全部後缀,利用pre存某字符的全部前缀,chars存全部出現的字符。
2. 在建前缀和後缀map的過程中,s存上一個字串,t存當前字串,模擬字典序比较,按位比较,不相同说明當前字元是上個字串對應位置字元的後缀
3. head存拓樸排序當前的起点(即入度为0的字元,沒有前綴的意思),故首先遍歷pre,因為p.first一定有前缀,不能作起點,先從head中清除。
4. 每次取出head的頭部,即起點,加入答案中,然後清除,遍歷後缀,找連接起點的字元,刪除前綴,如果刪除後字元前缀為空,也可以成為起點,加入head。
*/
class Solution {
public:
    string alienOrder(vector<string> &words) {
        map<char, set<char>> suc, pre;
        set<char> chars;
        string s;
        for (string t : words) {
            chars.insert(t.begin(), t.end());
            for (int i = 0; i < min(t.size(), s.size()); i++) {
                char a = s[i], b = t[i];
                if (a != b) {
                    pre[b].insert(a);
                    suc[a].insert(b);
                    break;
                }
            }
            s = t;
        }

        set<char> head = chars;
        for (auto p : pre)
            head.erase(p.first);
        string order;
        while (head.size()) {
            auto it = head.begin();
            char c = *it;
            head.erase(c);
            order += c;
            for (auto i : suc[c]) {
                pre[i].erase(c);
                if (pre[i].empty()) {
                    head.insert(i);
                }
            }
        }
        // return order; -> false
        return order.size() == chars.size() ? order : "";
    }
};
tags: BFS

2019年11月12日 星期二

Sliding Puzzle II


Sliding Puzzle II

  • Lintcode : 794 / Leetcode : 773 similar
  • Level : Hard

Problem

On a 3x3 board, there are 8 tiles represented by the integers 1 through 8, and an empty square represented by 0.

A move consists of choosing 0 and a 4-directionally adjacent number and swapping it.

Given an initial state of the puzzle board and final state, return the least number of moves required so that the initial state to final state.

If it is impossible to move from initial state to final state, return -1.

Example
Example 1:

Input:
[
 [2,8,3],
 [1,0,4],
 [7,6,5]
]
[
 [1,2,3],
 [8,0,4],
 [7,6,5]
]
Output:
4

Explanation:
[                 [
 [2,8,3],          [2,0,3],
 [1,0,4],   -->    [1,8,4],
 [7,6,5]           [7,6,5]
]                 ]

[                 [
 [2,0,3],          [0,2,3],
 [1,8,4],   -->    [1,8,4],
 [7,6,5]           [7,6,5]
]                 ]

[                 [
 [0,2,3],          [1,2,3],
 [1,8,4],   -->    [0,8,4],
 [7,6,5]           [7,6,5]
]                 ]

[                 [
 [1,2,3],          [1,2,3],
 [0,8,4],   -->    [8,0,4],
 [7,6,5]           [7,6,5]
]                 ]
Example 2:

Input:
[[2,3,8],[7,0,5],[1,6,4]]
[[1,2,3],[8,0,4],[7,6,5]]
Output:
-1
Challenge
How to optimize the memory?
Can you solve it with A* algorithm?

Concept & Algorithm

Time Complexity & Space Complexity

time : O()
space: O()

Answer

class Solution {
public:
    int minMoveStep(vector<vector<int>> &init_state, vector<vector<int>> &final_state) {
        string initString = getString(init_state);
        string finalString = getString(final_state);

        queue<pair<string, int>> q;
        set<string> repeat;
        int index = getZeroPos(initString);
        q.push({initString, index});
        repeat.insert(initString);
        int step = 0;
        while (!q.empty()) {
            int size = q.size();
            for (int i = 0; i < size; i++) {
                pair<string, int> s = q.front(); q.pop();
                string res = s.first;
                int pos = s.second;

                if (res.compare(finalString) == 0) return step;
                for (auto d : dir) {
                    string str = res;
                    int x = pos / 3 + d[0];
                    int y = pos % 3 + d[1];
                    if (x < 0 || y < 0 || x >= 3 || y >= 3) continue;
                    int newIndex = x * 3 + y;
                    swap(str[newIndex], str[pos]);
                    if (repeat.find(str) != repeat.end()) continue;

                    q.push({str, newIndex});
                    repeat.insert(str);
                }
            }
            step++;
        }
        return -1;
    }
    vector<vector<int>> dir = {{1, 0}, {0, -1}, {-1, 0}, {0, 1}};
    int getZeroPos (string &s) {
        for (int i = 0; i < 9; i++) {
            if (s[i] == '0') return i;
        }
    }
    string getString (vector<vector<int>> &str) {
        string res = "";
        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 3; j++) {
                res.push_back('0' + str[i][j]);
            }
        }
        return res;
    }
};
tags: BFS

Binary Tree Level Order Traversal II


Binary Tree Level Order Traversal II

  • Lintcode : 70 / Leetcode : 107
  • Level : Medium

Problem

Given a binary tree, return the bottom-up level order traversal of its nodes' values. (ie, from left to right, level by level from leaf to root).

Example
Example 1:

Input:
{1,2,3}
Output:
[[2,3],[1]]
Explanation:
    1
   / \
  2   3
it will be serialized {1,2,3}
level order traversal
Example 2:

Input:
{3,9,20,#,#,15,7}
Output:
[[15,7],[9,20],[3]]
Explanation:
    3
   / \
  9  20
    /  \
   15   7
it will be serialized {3,9,20,#,#,15,7}
level order traversal

Concept & Algorithm

Time Complexity & Space Complexity

time : O(n)
space: O(n)

Answer

/**
 * Definition of TreeNode:
 * class TreeNode {
 * public:
 *     int val;
 *     TreeNode *left, *right;
 *     TreeNode(int val) {
 *         this->val = val;
 *         this->left = this->right = NULL;
 *     }
 * }
 */

class Solution {
public:
    vector<vector<int>> levelOrderBottom(TreeNode * root) {
        vector<vector<int>> ans;
        if (root == nullptr) return ans;
        queue<TreeNode*> q;
        q.push(root);
        while(!q.empty()) {
            int s = q.size();
            vector<int> res;
            for (int i = 0; i < s; i++) {
                TreeNode* p = q.front(); q.pop();
                res.push_back(p -> val);
                if (p -> left) q.push(p -> left);
                if (p -> right) q.push(p -> right);
            }
            ans.insert(ans.begin(), res);
        }
        return ans;
    }
};
tags: BFS

Binary Tree Zigzag Level Order Traversal


Binary Tree Zigzag Level Order Traversal

  • Lintcode : 71 / Leetcode : 103
  • Level : Medium

Problem

Given a binary tree, return the zigzag level order traversal of its nodes' values. (ie, from left to right, then right to left for the next level and alternate between).

Example
Example 1:

Input:{1,2,3}
Output:[[1],[3,2]]
Explanation:
    1
   / \
  2   3
it will be serialized {1,2,3}
Example 2:

Input:{3,9,20,#,#,15,7}
Output:[[3],[20,9],[15,7]]
Explanation:
    3
   / \
  9  20
    /  \
   15   7
it will be serialized {3,9,20,#,#,15,7}

Concept & Algorithm

Time Complexity & Space Complexity

time : O(n)
space: O(n)

Answer

/**
 * Definition of TreeNode:
 * class TreeNode {
 * public:
 *     int val;
 *     TreeNode *left, *right;
 *     TreeNode(int val) {
 *         this->val = val;
 *         this->left = this->right = NULL;
 *     }
 * }
 */

class Solution {
public:
    vector<vector<int>> zigzagLevelOrder(TreeNode * root) {
        int row = 1;
        vector<vector<int>> ans;
        if (root == nullptr) return ans;
        queue<TreeNode*> q;
        q.push(root);
        while (!q.empty()) {
            int s = q.size();
            vector<int> res;
            for (int i = 0; i < s; i++) {
                TreeNode* p = q.front(); q.pop();
                res.push_back(p -> val);
                if (p -> left) q.push(p -> left);
                if (p -> right) q.push(p -> right);
            }
            if (row % 2 == 0) {
                reverse(res.begin(), res.end());
            } 
            ans.push_back(res);
            row++;
        }
        return ans;
    }
};
tags: BFS

Connected Component in Undirected Graph


Connected Component in Undirected Graph

  • Lintcode : 431 / Leetcode : 323
  • Level : Medium

Problem

Find connected component in undirected graph.

Each node in the graph contains a label and a list of its neighbors.

(A connected component of an undirected graph is a subgraph in which any two vertices are connected to each other by paths, and which is connected to no additional vertices in the supergraph.)

You need return a list of label set.

Example
Example 1:

Input: {1,2,4#2,1,4#3,5#4,1,2#5,3}
Output: [[1,2,4],[3,5]]
Explanation:

  1------2  3
   \     |  | 
    \    |  |
     \   |  |
      \  |  |
        4   5
Example 2:

Input: {1,2#2,1}
Output: [[1,2]]
Explanation:

  1--2

Clarification
Learn more about representation of graphs

Notice
Nodes in a connected component should sort by label in ascending order. Different connected components can be in any order.

Concept & Algorithm

Time Complexity & Space Complexity

time : O(n)
space: O(n)

Answer

/**
 * Definition for Undirected graph.
 * struct UndirectedGraphNode {
 *     int label;
 *     vector<UndirectedGraphNode *> neighbors;
 *     UndirectedGraphNode(int x) : label(x) {};
 * };
 */

class Solution {
public:
    vector<vector<int>> connectedSet(vector<UndirectedGraphNode*> nodes) {
        set<UndirectedGraphNode*> repeat;
        vector<vector<int>> ans;
        for (auto n : nodes) {
            if (repeat.find(n) != repeat.end()) continue;
            bfs (n, repeat, ans);
        }
        return ans;
    }

    void bfs (UndirectedGraphNode* n, set<UndirectedGraphNode*> &repeat, vector<vector<int>> &ans) {
        if (n == nullptr) return;
        vector<int> res;
        queue<UndirectedGraphNode*> q;
        q.push(n);
        repeat.insert(n);
        while (!q.empty()) {
            UndirectedGraphNode* node = q.front(); q.pop();
            res.push_back(node -> label);
            for (auto neighbor : node -> neighbors) {
                if (repeat.find(neighbor) != repeat.end()) continue;
                q.push(neighbor);
                repeat.insert(neighbor);
            }
        }
        sort(res.begin(), res.end());
        ans.push_back(res);
    }
};
tags: BFS

Build Post Office II


Build Post Office II

  • Lintcode : 573 / Leetcode :
  • Level : Hard

Problem

Given a 2D grid, each cell is either a wall 2, an house 1 or empty 0 (the number zero, one, two), find a place to build a post office so that the sum of the distance from the post office to all the houses is smallest.

Return the smallest sum of distance. Return -1 if it is not possible.

Example
Example 1:

Input:[[0,1,0,0,0],[1,0,0,2,1],[0,1,0,0,0]]
Output:8
Explanation: Placing a post office at (1,1), the distance that post office to all the house sum is smallest.
Example 2:

Input:[[0,1,0],[1,0,1],[0,1,0]]
Output:4
Explanation: Placing a post office at (1,1), the distance that post office to all the house sum is smallest.
Challenge
Solve this problem within O(n^3) time.

Notice
You cannot pass through wall and house, but can pass through empty.
You only build post office on an empty.

Concept & Algorithm

Time Complexity & Space Complexity

time : O(m n mn)
space: O(m * n)

Answer

class Solution {
public:
    int shortestDistance(vector<vector<int>> &grid) {
        int house = 0;
        int m = grid.size(), n = grid[0].size();
        vector<vector<bool>> isVisited(m, vector<bool>(n, false));
        vector<vector<int>> stepSum(m, vector<int>(n));
        vector<vector<int>> houseNum(m, vector<int>(n));
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                if (grid[i][j] == 1) {
                    bfs(grid, isVisited, stepSum, houseNum, i, j);
                    house += 1;
                }
            }
        }
        int minLen = INT_MAX;
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                if (grid[i][j] == 0 && houseNum[i][j] == house) {
                    minLen = min(minLen, stepSum[i][j]);
                }
            }
        }
        return minLen == INT_MAX ? -1 : minLen;
    }
    vector<vector<int>> dir = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
    void bfs(vector<vector<int>> &grid, vector<vector<bool>> isVisited, vector<vector<int>> &stepSum, vector<vector<int>> &houseNum, int i, int j) {
        int step = 1;
        queue<vector<int>> q;
        q.push({i, j});
        isVisited[i][j] = true;
        while (!q.empty()) {
            int size = q.size();
            for (int k = 0; k < size; k++) {
                vector<int> pair = q.front(); q.pop();
                for (auto d : dir) {
                    int x = d[0] + pair[0];
                    int y = d[1] + pair[1];
                    if (!isValid(grid, x, y) || isVisited[x][y]) continue;
                    q.push({x, y});
                    isVisited[x][y] = true;
                    stepSum[x][y] += step;
                    houseNum[x][y] += 1;
                }
            }
            step++;
        }
    }
    bool isValid(vector<vector<int>> &grid, int x, int y) {
        if (x < 0 || y < 0 || x >= grid.size() || y >= grid[0].size() || grid[x][y] != 0)
            return false;
        return true;
    }
};
tags: BFS

Last Position of Target

Last Position of Target Lintcode : 458 / Leetcode : 34 Level : Easy Problem Find the last position of a target number in a sorted ...