iOS开发寻找最近公共view

新技能

#pragma mark --寻找最近公共view

+ (NSArray *)superViews:(UIView *)view{

    if (view==nil) {

        return @[];

    }

    NSMutableArray *result = [NSMutableArray array];

    while (view!=nil) {

        [result addObject:view];

        view = view.superview;

    }

    return [result copy];

}

//然后对于两个ViewA,viewB,我们可以得到两个路径,找到的是最近的一个公共节点。

//一个简单直接的方法:拿第一个路径中的所有节点,去第二个节点中查找。假设路的平均长度是N,因为每个节点都要找N次,一共有N个节点,所以这个方法的时间复杂度O(N^2)

+ (UIView *)commonView_1:(UIView *)viewA  andView:(UIView *)viewB{

    

    NSArray *arr1 = [self superViews:viewA];

    NSArray *arr2 = [self superViews:viewB];

    for (NSUInteger i =0; i<arr1.count; ++i) {

        UIView *targetView = arr1[i];

        for (NSUInteger j=0; j<arr2.count; ++j) {

            if (targetView == arr2[j]) {

                return targetView;

            }

        }

    }

    return nil;

}

//一个改进的办法:我们将一个路径中的所有点先放进NSSet中.因为NSSet的内部实现是一个hash表,所以查询元素的时间的复杂度变成O(1),我们一共有N个节点,所以总时间复杂度优化到了O(N)

+ (UIView *)commomView_2:(UIView *)viewA andView:(UIView *)viewB{

    NSArray *arr1 = [self superViews:viewA];

    NSArray *arr2 = [self superViews:viewB];

    NSSet *set = [NSSet setWithArray:arr2];

    for (NSUInteger i =0; i<arr1.count; ++i) {

        UIView *targetView = arr1[i];

        if ([set containsObject:targetView]) {

            return targetView;

        }

    }

    return nil;

}

//除了使用NSSet外,我们还可以使用类似归并排序的思想,用两个指针,分别指向两个路径的根节点,然后从根节点

+ (UIView *)commonView_3:(UIView *)viewA andView:(UIView *)viewB{

    NSArray *arr1 = [self superViews:viewA];

    NSArray *arr2 = [self superViews:viewB];

    NSInteger p1 = arr1.count -1;

    NSInteger p2 = arr2.count -1;

    UIView *answer = nil;

    while (p1>=0&p2>=0) {

        if (arr1[p1]==arr2[p2]) {

            answer = arr1[p1];

        }

        p1--;

        p2--;

    }

    return answer;

}

 

转载于:https://www.cnblogs.com/tryFighting/p/6379611.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值