You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于给定好友关系矩阵,优化指定男性好友及二度好友查询方案建议

Hey there! I see you've already implemented a solution for finding direct friends and second-degree friends (friends of friends) using loops and recursion, but you're looking for better approaches. Let's dive into some optimized ideas that'll make your code cleaner, more efficient, and easier to maintain.

First, let's clarify the friend relationship matrix you provided into a more readable structure (since the original format is a bit messy):

MenDirect Friends
AB, C, D
BE, F
CA
EB
FB
GF

Optimized Implementation Ideas

1. Store Relationships as an Adjacency List (Graph Data Structure)

Instead of working with the raw matrix, convert the friend relationships into an adjacency list (a dictionary where each key is a man, and the value is a set of his direct friends). This gives you O(1) lookups for direct friends, and sets automatically handle duplicates.

Example in Python:

# Adjacency list using sets for O(1) lookups and built-in deduplication
friend_graph = {
    'A': {'B', 'C', 'D'},
    'B': {'E', 'F'},
    'C': {'A'},
    'E': {'B'},
    'F': {'B'},
    'G': {'F'}
}

This structure is far more efficient to work with than looping through a raw matrix, and it lays the groundwork for all the other optimized approaches.

2. Use Breadth-First Search (BFS) for Hierarchical Lookup

BFS is perfect for this problem because it naturally handles layered relationships (direct friends = level 1, friends of friends = level 2). Unlike recursion, it avoids stack overflow risks (even if your friend network grows large) and has a clear, linear flow.

Here's how to implement it:

def get_second_degree_friends(target, graph):
    second_degree = set()
    
    # Add direct friends (level 1)
    direct_friends = graph.get(target, set())
    second_degree.update(direct_friends)
    
    # Add friends of friends (level 2), excluding the target themselves
    for friend in direct_friends:
        friends_of_friend = graph.get(friend, set())
        friends_of_friend.discard(target)  # Don't include the target in their own friend list
        second_degree.update(friends_of_friend)
    
    return second_degree

# Test with target 'G'
print(get_second_degree_friends('G', friend_graph))  # Output: {'F', 'B', 'E'}

Why this is better:

  • Time complexity of O(N) (N = total number of people in the network), which is more efficient than recursive approaches for larger datasets.
  • Logic is straightforward and easy to debug/maintain.
  • Built-in deduplication via sets means you don't have to manually filter out duplicates like in your original solution.

3. Simplify with Set Operations

If you prefer concise code, you can leverage Python's built-in set union and difference operations to achieve the same result in fewer lines. This approach is just as efficient as BFS and reads like plain English.

def get_second_degree_friends(target, graph):
    direct_friends = graph.get(target, set())
    # Get all friends of direct friends
    friends_of_friends = set().union(*[graph.get(f, set()) for f in direct_friends])
    # Combine direct friends and their friends, then remove the target themselves
    return (direct_friends | friends_of_friends) - {target}

# Test with 'G'
print(get_second_degree_friends('G', friend_graph))  # Output: {'F', 'B', 'E'}

Why this is better:

  • Extremely concise and readable code.
  • Uses optimized built-in set operations, which are implemented in C under the hood (faster than manual loops).

4. Cache Results for High-Frequency Queries

If you need to run this lookup multiple times (e.g., for different users), adding a cache will avoid redundant calculations and speed up repeated queries.

from functools import lru_cache

# Convert the graph to use tuples (since sets are not hashable for LRU cache)
friend_graph_tuple = {k: tuple(v) for k, v in friend_graph.items()}

@lru_cache(maxsize=None)
def get_second_degree_friends_cached(target):
    direct_friends = set(friend_graph_tuple.get(target, ()))
    friends_of_friends = set().union(*[set(friend_graph_tuple.get(f, ())) for f in direct_friends])
    return frozenset((direct_friends | friends_of_friends) - {target})

# Test with 'G'
print(get_second_degree_friends_cached('G'))  # Output: frozenset({'F', 'B', 'E'})

Why this is better:

  • Caches computed results so repeated queries for the same target are returned instantly.
  • Great for applications where friend lookups are frequent (like social media tools).

Key Advantages Over Your Original Loop/Recursion Solution

  • Efficiency: Adjacency lists and set operations reduce lookup time from O(N) per friend to O(1).
  • Readability: BFS and set-based logic are more intuitive than nested loops or recursion.
  • Deduplication: Sets handle duplicates automatically, so you don't have to write extra code to filter out entries like F,B,E,F,B.
  • Scalability: BFS can easily be extended to find 3rd, 4th, or N-degree friends—just add more levels to the traversal.

内容的提问来源于stack exchange,提问作者Mukesh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 07:55:48