跳至主要内容

268 篇文章 含有標籤「leetcode」

檢視所有標籤

2285. Maximum Total Importance of Roads

· 閱讀時間約 2 分鐘

這題目的要點如下:

  1. 你有 n 個城市和一些連接城市的道路。
  2. 你需要給每個城市分配一個從 1 到 n 的重要性值,每個數字只能用一次。
  3. 一條道路的重要性是它連接的兩個城市的重要性值之和。
  4. 你的目標是最大化所有道路的重要性總和。

解題思路:

  1. 關鍵觀察:連接度(即與其他城市相連的道路數)較高的城市應該獲得較高的重要性值。
  2. 計算每個城市的連接度。
  3. 根據連接度對城市進行排序。
  4. 將最高的重要性值(n)分配給連接度最高的城市,次高的重要性值(n-1)分配給連接度次高的城市,以此類推。
  5. 計算所有道路的重要性總和。

這種方法可以保證獲得最大的總重要性,因為它確保了連接度高的城市獲得高的重要性值,從而最大化了每條道路的貢獻。

#define ll long long

class Solution {
public:
long long maximumImportance(int n, vector<vector<int>>& roads)
{
vector<ll> city(n);
// 計算與多少城市相連
for(auto road : roads)
{
city[road[0]]++;
city[road[1]]++;
}

sort(city.begin(), city.end());

ll res = 0;
// city = [1, 2, 2, 3, 4]
// 1, 2, 3, 4, 5
// 1 + 4 + 6 + 12 + 20 = 43
// res += 與多少城市相連 * 城市的數目加權
for (int i = 0; i < n; ++i)
{
res += (i + 1) * city[i];
}
return res;
}
};
  • T: $O(n^2)$
  • S: $O(n)$

2259. Remove Digit From Number to Maximize Result

· 閱讀時間約 1 分鐘

Hint

class Solution {
public:
string removeDigit(string number, char digit)
{
string res;
for (int i = 0; i < number.size(); i++)
{
if (number[i] == digit)
{
string temp = number.substr(0, i) + number.substr(i + 1, number.size());
res = max(res, temp);
}
}
return res;
}
};
  • T: $O(n)$
  • S: $O(1)$

2220. Minimum Bit Flips to Convert Number

· 閱讀時間約 1 分鐘
class Solution {
public:
int minBitFlips(int start, int goal)
{
int n = start ^ goal;
int cnt = 0;
while (n)
{
n &= (n - 1);
cnt++;
}
return cnt;
}
};
  • T: $O(number of bits)$
  • S: $O(1)$

2196. Create Binary Tree From Descriptions

· 閱讀時間約 3 分鐘

Hint

/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr, right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
TreeNode* createBinaryTree(vector<vector<int>>& descriptions)
{
// Map to store TreeNode pointers by their values
// Set to keep track of all child nodes

// Iterate over each description in the input
for ()
{
// Parent node value
// Child node value
// Indicates if the child is a left child

// If parent node is not already created, create it and store in nodeMap

// If child node is not already created, create it and store in nodeMap

// Attach the child to the appropriate side of the parent

// Add the child value to the set of children
}

// Find and return the root node (a node that is not anyone's child)
for ()
{
// If the value is not found in children set, it's the root
}
// If no root is found (though the problem guarantees there will be one), return nullptr
}
};
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr, right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
TreeNode* createBinaryTree(vector<vector<int>>& descriptions)
{
// Map to store TreeNode pointers by their values
unordered_map<int, TreeNode*> nodeMap;

// Set to keep track of all child nodes
unordered_set<int> children;

// Iterate over each description in the input
for (const auto& description : descriptions)
{
// Parent node value
int parentValue = description[0];

// Child node value
int childValue = description[1];

// Indicates if the child is a left child
bool isLeft = description[2];

// If parent node is not already created, create it and store in nodeMap
if (!nodeMap.count(parentValue))
{
nodeMap[parentValue] = new TreeNode(parentValue);
}

// If child node is not already created, create it and store in nodeMap
if (!nodeMap.count(childValue))
{
nodeMap[childValue] = new TreeNode(childValue);
}

// Attach the child to the appropriate side of the parent
if (isLeft)
{
nodeMap[parentValue]->left = nodeMap[childValue];
}
else
{
nodeMap[parentValue]->right = nodeMap[childValue];
}

// Add the child value to the set of children
children.insert(childValue);
}

// Find and return the root node (a node that is not anyone's child)
for (auto& entry : nodeMap)
{
auto& value = entry.first;
auto& node = entry.second;

// If the value is not found in children set, it's the root
if (!children.count(value))
{
return node;
}
}

// If no root is found (though the problem guarantees there will be one), return nullptr
return nullptr;
}
};

  • T: $O(n)$
  • S: $O(n)$

2191. Sort the Jumbled Numbers

· 閱讀時間約 1 分鐘
class Solution {
public:
vector<int> sortJumbled(vector<int>& mapping, vector<int>& nums)
{
vector<pair<int, int>> m;

for (int i = 0; i < nums.size(); ++i)
{
string number = to_string(nums[i]);
string formed = "";
for (int j = 0; j < number.size(); ++j)
{
formed = formed + (to_string(mapping[number[j] - '0']));
}
int mappedValue = stoi(formed);
m.push_back({mappedValue, i});
}

sort(m.begin(), m.end());

vector<int> res;

for (auto pair : m)
{
res.push_back(nums[pair.second]);
}
return res;
}
};
  • T: $O(n \cdot \log n)$
  • S: $O(n)$

2133. Check if Every Row and Column Contains All Numbers

· 閱讀時間約 1 分鐘

Hint

class Solution {
public:
bool checkValid(vector<vector<int>>& matrix)
{
int n = matrix.size();
unordered_set<int> rowSet, colSet;
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
if (rowSet.count(matrix[i][j]))
{
return false;
}
else
{
rowSet.insert(matrix[i][j]);
}
if (colSet.count(matrix[j][i]))
{
return false;
}
else
{
colSet.insert(matrix[j][i]);
}
}
rowSet.clear();
colSet.clear();
}
return true;
}
};
  • T: $O(n^2)$
  • S: $O(n)$

2096. Step-By-Step Directions From a Binary Tree Node to Another

· 閱讀時間約 2 分鐘

Hint

/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
string getDirections(TreeNode* root, int startValue, int destValue)
{
// Strings to store paths from root to startValue and destValue
// Find paths from root to startValue and destValue

// Initialize directions string
// Length of common path

// Find the length of the common path prefix
while ()
{
}

// Append 'U' (up) moves to go from startValue to the common ancestor
for ()
{
}

// Append moves to go from the common ancestor to destValue
for ()
{
}
// Return the directions
}

// Function to find the path from root to target value and update the path string
bool findPath()
{
// Base case: If root is null, return false
// If the current node's value matches the target, return true indicating target found

// Append 'L' (left) and recursively search in the left subtree
// Backtrack by removing the last character

// Append 'R' (right) and recursively search in the right subtree
// Backtrack by removing the last character

// Return false if target is not found in the subtree
}
};
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
string getDirections(TreeNode* root, int startValue, int destValue)
{
string startPath, destPath;
findPath(root, startValue, startPath);
findPath(root, destValue, destPath);

string directions;
int commonPath = 0;

while (commonPath < startPath.size() && commonPath < destPath.size() && startPath[commonPath] == destPath[commonPath])
{
commonPath++;
}

for (int i = commonPath; i < startPath.size(); ++i)
{
directions += "U";
}

for (int i = commonPath; i < destPath.size(); ++i)
{
directions += destPath[i];
}
return directions;
}

bool findPath(TreeNode* root, int target, string& path)
{
if (!root) return false;
if (root->val == target) return true;

path += 'L';
if (findPath(root->left, target, path)) return true;
path.pop_back();

path += 'R';
if (findPath(root->right, target, path)) return true;
path.pop_back();

return false;
}
};
  • T: $O(n)$
  • S: $O(n)$

2058. Find the Minimum and Maximum Number of Nodes Between Critical Points

· 閱讀時間約 2 分鐘

這道題目要求我們在一個 linked list中找出關鍵點之間的最小和最大節點數。以下是題目的主要內容:

  1. 我們有一個 linked list,每個節點都有一個值。
  2. 關鍵點定義為滿足以下條件之一的節點(不包括頭尾節點):
    • 局部最大值:該節點的值大於前一個節點和後一個節點的值。
    • 局部最小值:該節點的值小於前一個節點和後一個節點的值。
  3. 我們需要找出:
    • 任意兩個關鍵點之間的最小距離
    • 第一個和最後一個關鍵點之間的距離
  4. 如果關鍵點少於兩個,則返回 [-1, -1]。

解題思路:

  1. 走訪 linked list,找出所有的關鍵點。
  2. 記錄每個關鍵點的索引位置。
  3. 計算相鄰關鍵點之間的最小距離。
  4. 計算第一個和最後一個關鍵點之間的距離。
  5. 返回結果。

初始化:

  • minDist 初始化為整數的最大值,用於記錄最小距離。
  • prevcur 分別初始化為 linked list 的第一個和第二個節點。
  • i 是當前節點的索引,從 1 開始。
  • lastfirst 用於記錄最後一個和第一個關鍵點的索引。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
vector<int> nodesBetweenCriticalPoints(ListNode* head)
{
vector<int> res = {-1, -1};
int minDist = INT_MAX;

ListNode* prev = head;
ListNode* cur = head->next;

int i = 1;
int last = 0;
int first = 0;

while (cur->next)
{
// if (localMinimum || localMaximum)
if ((cur->val < prev->val && cur->val < cur->next->val) || (cur->val > prev->val && cur->val > cur->next->val))
{
// 如果這是第一個 critial point,則將 last 和 first 都設為當前的 index i。
if (last == 0)
{
last = i;
first = i;
}
else
{
minDist = min(minDist, i - last);
// 更新 last critial point
last = i;
}
}
i++;
// update the pointer
prev = cur;
cur = cur->next;
}

if (minDist != INT_MAX)
{
// maxDist 即為 last - first
int maxDist = last - first;
res = {minDist, maxDist};
}
return res;
}
};
  • T: $O(n)$
  • S: $O(1)$

2053. Kth Distinct String in an Array

· 閱讀時間約 1 分鐘

Hint

class Solution {
public:
string kthDistinct(vector<string>& arr, int k)
{
unordered_map<string, int> m;
for (const auto& str : arr) m[str]++;
for (const auto& num : arr)
{
if (m[num] == 1 && !--k) return num;
}
return "";
}
};
  • T: $O(n)$
  • S: $O(n)$