1. 程式人生 > >[LeetCode] Shortest Word Distance III 最短單詞距離之三

[LeetCode] Shortest Word Distance III 最短單詞距離之三

This is a follow up of Shortest Word Distance. The only difference is now word1 could be the same as word2.

Given a list of words and two words word1 and word2, return the shortest distance between these two words in the list.

word1 and word2 may be the same and they represent two individual words in the list.

For example,
Assume that words = ["practice", "makes", "perfect", "coding", "makes"].

Given word1 = “makes”, word2 = “coding”, return 1.
Given word1 = "makes", word2 = "makes", return 3.

Note:
You may assume word1 and word2 are both in the list.

這道題還是讓我們求最短單詞距離,有了之前兩道題Shortest Word Distance II

Shortest Word Distance的基礎,就大大降低了題目本身的難度。這道題增加了一個條件,就是說兩個單詞可能會相同,所以在第一題中的解法的基礎上做一些修改,我最先想的解法是基於第一題中的解法二,由於會有相同的單詞的情況,那麼p1和p2就會相同,這樣結果就會變成0,顯然不對,所以我們要對word1和word2是否的相等的情況分開處理,如果相等了,由於p1和p2會相同,所以我們需要一個變數t來記錄上一個位置,這樣如果t不為-1,且和當前的p1不同,我們可以更新結果,如果word1和word2不等,那麼還是按原來的方法做,參見程式碼如下:

解法一:

class Solution {
public: int shortestWordDistance(vector<string>& words, string word1, string word2) { int p1 = -1, p2 = -1, res = INT_MAX; for (int i = 0; i < words.size(); ++i) { int t = p1; if (words[i] == word1) p1 = i; if (words[i] == word2) p2 = i; if (p1 != -1 && p2 != -1) { if (word1 == word2 && t != -1 && t != p1) { res = min(res, abs(t - p1)); } else if (p1 != p2) { res = min(res, abs(p1 - p2)); } } } return res; } };

上述程式碼其實可以優化一下,我們並不需要變數t來記錄上一個位置,我們將p1初始化為陣列長度,p2初始化為陣列長度的相反數,然後當word1和word2相等的情況,我們用p1來儲存p2的結果,p2賦為當前的位置i,這樣我們就可以更新結果了,如果word1和word2不相等,則還跟原來的做法一樣,這種思路真是挺巧妙的,參見程式碼如下:

解法二:

class Solution {
public:
    int shortestWordDistance(vector<string>& words, string word1, string word2) {
        int p1 = words.size(), p2 = -words.size(), res = INT_MAX;
        for (int i = 0; i < words.size(); ++i) {
            if (words[i] == word1) p1 = word1 == word2 ? p2 : i;
            if (words[i] == word2) p2 = i;
            res = min(res, abs(p1 - p2));
        }
        return res;
    }
};

我們再來看一種更進一步優化的方法,只用一個變數idx,這個idx的作用就相當於記錄上一次的位置,當前idx不等-1時,說明當前i和idx不同,然後我們在word1和word2相同或者words[i]和words[idx]相同的情況下更新結果,最後別忘了將idx賦為i,參見程式碼如下;

解法三:

class Solution {
public:
    int shortestWordDistance(vector<string>& words, string word1, string word2) {
        int idx = -1, res = INT_MAX;
        for (int i = 0; i < words.size(); ++i) {
            if (words[i] == word1 || words[i] == word2) {
                if (idx != -1 && (word1 == word2 || words[i] != words[idx])) {
                    res = min(res, i - idx);
                }
                idx = i;
            }
        }
        return res;
    }
};

類似題目:

參考資料: