class Solution {
public:
int longestMountain(vector<int>& arr) {
int n = arr.size();
if (n < 3) {
return 0; // 如果数组长度小于 3,直接返回 0
}
vector<int> left(n, 0); // 记录每个位置左侧严格递增的长度
for (int i = 1; i < n; ++i) {
if (arr[i - 1] < arr[i]) {
left[i] = left[i - 1] + 1;
}
}
vector<int> right(n, 0); // 记录每个位置右侧严格递减的长度
for (int i = n - 2; i >= 0; --i) {
if (arr[i + 1] < arr[i]) {
right[i] = right[i + 1] + 1;
}
}
int ret = 0;
for (int i = 0; i < n; ++i) {
if (left[i] > 0 && right[i] > 0) { // 如果 i 是山峰
ret = max(ret, left[i] + right[i] + 1); // 计算山脉长度
}
}
return ret;
}
};
c++复制代码
class Solution {
public:
int longestMountain(vector<int>& arr) {
int n = arr.size();
int ret = 0;
int left = 0;
while (left + 2 < n) {
int right = left + 1;
if (arr[left] < arr[left + 1]) {
while (right + 1 < n && arr[right] < arr[right + 1]) {
++right;
}
if (right < n - 1 && arr[right] > arr[right + 1]) {
while (right < n - 1 && arr[right] > arr[right + 1]) {
++right;
}
ret = max(ret, right - left + 1);
} else {
++right;
}
}
left = right;
}
return ret;
}
};
Java
java复制代码
class Solution {
public int longestMountain(int[] arr) {
int n = arr.length;
if (n < 3) {
return 0; // 如果数组长度小于3,直接返回0
}
int[] left = new int[n]; // 记录每个位置左侧严格递增的长度
for (int i = 1; i < n; ++i) {
if (arr[i - 1] < arr[i]) {
left[i] = left[i - 1] + 1;
}
}
int[] right = new int[n]; // 记录每个位置右侧严格递减的长度
for (int i = n - 2; i >= 0; --i) {
if (arr[i + 1] < arr[i]) {
right[i] = right[i + 1] + 1;
}
}
int ret = 0;
for (int i = 0; i < n; ++i) {
if (left[i] > 0 && right[i] > 0) { // 如果i是山峰
ret = Math.max(ret, left[i] + right[i] + 1); // 计算山脉长度
}
}
return ret;
}
}
Python
python复制代码
class Solution:
def longestMountain(self, arr: List[int]) -> int:
n = len(arr)
if n < 3:
return 0 # 如果数组长度小于3,直接返回0
left = [0] * n # 记录每个位置左侧严格递增的长度
for i in range(1, n):
if arr[i - 1] < arr[i]:
left[i] = left[i - 1] + 1
right = [0] * n # 记录每个位置右侧严格递减的长度
for i in range(n - 2, -1, -1):
if arr[i + 1] < arr[i]:
right[i] = right[i + 1] + 1
ret = 0
for i in range(n):
if left[i] > 0 and right[i] > 0: # 如果i是山峰
ret = max(ret, left[i] + right[i] + 1) # 计算山脉长度
return ret
需要记录访问过的节点集合,通常用**位掩码(bitmask)**表示,其中第 i 位为 1 表示节点 i 已被访问。
使用 BFS 来探索所有可能的路径,确保找到最短路径。
算法设计 :
初始化:从每个节点出发,初始化队列,记录当前节点、访问掩码和路径长度。
BFS 遍历:对于队列中的每个状态,尝试访问相邻节点,并更新访问掩码。
终止条件:当访问掩码表示所有节点都被访问时,返回当前路径长度。
优化 :
使用 seen 数组避免重复访问相同的节点和掩码组合。
优先处理路径长度较短的状态,确保找到最短路径
3、代码实现
C++
c++复制代码
class Solution {
public:
int shortestPathLength(vector<vector<int>>& graph) {
int n = graph.size();
queue<tuple<int, int, int>> q; // 队列存储 (节点, 掩码, 路径长度)
vector<vector<bool>> seen(n, vector<bool>(1 << n, false)); // 标记是否访问过
// 初始化队列,从每个节点出发
for (int i = 0; i < n; ++i) {
q.emplace(i, 1 << i, 0);
seen[i][1 << i] = true;
}
int ret = 0;
while (!q.empty()) {
auto [u, mask, dist] = q.front();
q.pop();
// 如果所有节点都被访问,返回当前路径长度
if (mask == (1 << n) - 1) {
ret = dist;
break;
}
// 遍历相邻节点
for (int v : graph[u]) {
int mask_v = mask | (1 << v); // 更新掩码
if (!seen[v][mask_v]) {
q.emplace(v, mask_v, dist + 1);
seen[v][mask_v] = true;
}
}
}
return ret;
}
};
Java
java复制代码
class Solution {
public int shortestPathLength(int[][] graph) {
int n = graph.length;
Queue<int[]> q = new ArrayDeque<>(); // 队列存储 [节点, 掩码, 路径长度]
boolean[][] seen = new boolean[n][1 << n]; // 标记是否访问过
// 初始化队列,从每个节点出发
for (int i = 0; i < n; ++i) {
q.offer(new int[] { i, 1 << i, 0 });
seen[i][1 << i] = true;
}
int ret = 0;
while (!q.isEmpty()) {
int[] state = q.poll();
int u = state[0], mask = state[1], dist = state[2];
// 如果所有节点都被访问,返回当前路径长度
if (mask == (1 << n) - 1) {
ret = dist;
break;
}
// 遍历相邻节点
for (int v : graph[u]) {
int mask_v = mask | (1 << v); // 更新掩码
if (!seen[v][mask_v]) {
q.offer(new int[] { v, mask_v, dist + 1 });
seen[v][mask_v] = true;
}
}
}
return ret;
}
}
Python
python复制代码
class Solution:
def shortestPathLength(self, graph: List[List[int]]) -> int:
n = len(graph)
q = deque() # 队列存储 (节点, 掩码, 路径长度)
seen = [[False] * (1 << n) for _ in range(n)] # 标记是否访问过
# 初始化队列,从每个节点出发
for i in range(n):
q.append((i, 1 << i, 0))
seen[i][1 << i] = True
ret = 0
while q:
u, mask, dist = q.popleft()
# 如果所有节点都被访问,返回当前路径长度
if mask == (1 << n) - 1:
ret = dist
break
# 遍历相邻节点
for v in graph[u]:
mask_v = mask | (1 << v) # 更新掩码
if not seen[v][mask_v]:
q.append((v, mask_v, dist + 1))
seen[v][mask_v] = True
return ret