212. Word Search II && 215. Kth Largest Element in an Array

212. Word Search II

Given a 2D board and a list of words from the dictionary, find all words in the board.

Each word must be constructed from letters of sequentially adjacent cell, where “adjacent” cells are those horizontally or vertically neighboring. The same letter cell may not be used more than once in a word.

Example:

Input:
words = [“oath”,”pea”,”eat”,”rain”] and board =
[
[‘o’,’a’,’a’,’n’],
[‘e’,’t’,’a’,’e’],
[‘i’,’h’,’k’,’r’],
[‘i’,’f’,’l’,’v’]
]
Output: [“eat”,”oath”]

Note:
You may assume that all inputs are consist of lowercase letters a-z.


解题思路
法1:(backtracing)同Word Search,对每个单词使用一次查找匹配,但超时。
法2:(Trie + backtracing)使用Trie树,穷举所有单词走法,跟Trie树中的单词进行比较。为减少比较次数,每次前进前判断当前前缀是否存在。

程序

//使用Trie树,穷举所有board走法,跟Trie树中单词比较。为了减少比较次数,增加验证当前前缀是否存在的操作,类似剪枝
//1.编写Trie树的插入、查找、验证前缀
class Trie{
public:
    Trie * child[26] = {NULL};
    string word; //保存叶节点所表示的单词

    void insert(string & word){
        Trie * curr = this;
        for (auto letter:word){
            if (!curr->child[letter - 'a']){
                Trie * new_node = new Trie();
                curr->child[letter - 'a'] = new_node;
            }
            curr = curr->child[letter - 'a'];
        }
        curr->word = word;
    }

    bool find(string & word){
        Trie * curr = this;
        for (auto letter: word){
            if (!curr->child[letter - 'a']) return 0;
            curr = curr->child[letter - 'a'];
        }
        return curr->word == word;
    }

    bool is_prefix(string & prefix){
        Trie * curr = this;
        for (auto letter: prefix){
            if (!curr->child[letter - 'a']) return 0;
            curr = curr->child[letter - 'a'];
        }
        return 1;
    }
};
//2.穷举所有走法
class Solution {
public:
    vector<string> findWords(vector<vector<char>>& board, vector<string>& words) {
        sort(words.begin(), words.end());
        unordered_set<string> res;
        //create the trie
        Trie * root = new Trie();
        for (int i = 0; i < words.size(); i++)
            if (i > 0 and words[i] == words[i - 1]) continue;
            else root->insert(words[i]);
        //find all routes
        for (int i = 0; i < board.size(); i++)
            for (int j = 0; j < board[0].size(); j++)
                exist_from(board, root, res, i, j, "");
        return vector<string>(res.begin(), res.end());
    }

    void exist_from(vector<vector<char>>& board, Trie * root, unordered_set<string> &res, int i, int j, string pre){
        if (i < 0 || i >= board.size() || j < 0 || j >= board[0].size() || board[i][j] == '0' ||!root->is_prefix(pre)) return; 
        //if out of range or used or not prefix
        pre += board[i][j];
        if (root->find(pre)) res.insert(pre);
        board[i][j] = '0';
        exist_from(board, root, res, i - 1, j, pre);
        exist_from(board, root, res, i + 1, j, pre);
        exist_from(board, root, res, i, j - 1, pre);
        exist_from(board, root, res, i, j + 1, pre); 
        board[i][j] = pre[pre.size() - 1];
    }
};

215. Kth Largest Element in an Array

Find the **k**th largest element in an unsorted array. Note that it is the kth largest element in the sorted order, not the kth distinct element.

Example 1:

Input: [3,2,1,5,6,4] and k = 2
Output: 5

Example 2:

Input: [3,2,3,1,2,4,5,5,6] and k = 4
Output: 4

Note:
You may assume k is always valid, 1 ≤ k ≤ array’s length.

解题思路

法1:直接调用STL对应函数nth_element

法2:使用类似快排的方法,每次循环获得一个位置,直到这个位置与题目要求位置相同即可。

程序代码
class Solution {
public:
    //法1,调用nth_element函数
    /*
    int findKthLargest(vector<int>& nums, int k) {
        nth_element(nums.begin(), nums.begin() + nums.size() - k, nums.end());
        return nums[nums.size() - k];
    }
    */
    //法2,快排,每次取出一个中间位置,直到该位置恰好为目标位置即可。
    int partition(vector<int>& nums, int start, int end){
        int key = nums[end];
        int less = start;
        for (int i = start; i < end; i++){
            if (nums[i] < key){
                int temp = nums[i];
                nums[i] = nums[less];
                nums[less] = temp;
                less++;
            }
        }
        nums[end] = nums[less];
        nums[less] = key;
        return less;
    }
    int findKthLargest(vector<int>& nums, int k) {
        int target = nums.size() - k;
        int pos = 0;
        int start = 0, end = nums.size() - 1;
        while(start <= end){
            pos = partition(nums, start, end);
            if (pos == target) break;
            else if (pos < target) start = pos + 1;
            else end = pos - 1;
        }
        return nums[pos];
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值