【算法】Self Crossing 自我相交

本文深入解析SelfCrossing算法,针对一系列正数数组,通过一过性算法及O(1)额外空间判断路径是否自我相交。文章详细阐述了三种相交情况,并附带Swift代码实现。

【算法】Self Crossing 自我相交

题目

You are given an array x of n positive numbers. You start at point (0,0) and moves x[0] metres to the north, then x[1] metres to the west, x[2] metres to the south, x[3] metres to the east and so on. In other words, after each move your direction changes counter-clockwise.

Write a one-pass algorithm with O(1) extra space to determine, if your path crosses itself, or not.

Example 1:

┌───┐
│   │
└───┼──>
    │

Input: [2,1,1,2]
Output: true

Example 2:

┌──────┐
│      │
│
│
└────────────>

Input: [1,2,3,4]
Output: false 

Example 3:

┌───┐
│   │
└───┼>

Input: [1,1,1,1]
Output: true 

给出一个数字数组,按照上下左右的顺序,循环移动数组中相应的步数。
判断这组数字是否会导致路径与自我相交。

解题思路

经分析,大体分为以下三种情况:

   x(1)
    ┌───┐
x(2)│   │x(0)
    └───┼──>
    x(3)│
  • 第 4+4n 条边和第 1+4n 条边相交(n>=0),此时条件是第 4 条边大等于第 2 条边,第 1 条边大等于第 3 条边
      x(1)
    ┌──────┐
    │      │x(0)
x(2)│      ^
    │      │x(4)
    └──────│
      x(3)
  • 第 5+4n 条边和第 1+4n 条边相交(n>=0),此时条件是第 2 条边等于第 4 条边,第 5 条边大等于第 3、1 条边的差值
      x(1)
    ┌──────┐
    │      │x(0)
x(2)│     <│────│
    │       x(5)│x(4)
    └───────────│
        x(3)
  • 第 6+4n 条边和第 1+4n 条边相交(n>=0),此时条件是第 4 条边大等于第 2 条边,第 3 条边大等于第 5 条边,第 5 条边大等于第 3、1 条边的差值,第 6 条边大等于第 4、2 条边的差值

代码实现

Runtime: 8 ms
Memory: 20.7 MB

func isSelfCrossing(_ x: [Int]) -> Bool {
        // 变数大于 3 的时候才需要判断,小于等于 3 的时候一定不会相交
        if x.count > 3 {
            for i in 3 ..< x.count {
                // 第 4 条边大等于第 2 条边,第 1 条边大等于第 3 条边,此时第 4+4n 条边和第 1+4n 条边相交(n>=0)
                if (x[i] >= x[i - 2] && x[i - 3] >= x[i - 1]) {
                    return true;
                }
                // 第 2 条边等于第 4 条边,第 5 条边大等于第 3、1 条边的差值,此时第 5+4n 条边和第 1+4n 条边相交(n>=0)
                if (i >= 4 && x[i-1] == x[i-3] && x[i] >= x[i-2] - x[i-4]) {
                    return true;
                }
                // 第 4 条边大等于第 2 条边,第 3 条边大等于第 5 条边,第 5 条边大等于第 3、1 条边的差值,第 6 条边大等于第 4、2 条边的差值,此时第 6+4n 条边和第 1+4n 条边相交(n>=0)
                if (i >= 5 && x[i-2] >= x[i-4] && x[i-3] >= x[i-1] && x[i-1] >= x[i-3] - x[i-5] && x[i] >= x[i-2] - x[i-4]) {
                    return true;
                }
            }
        }
        return false
    }

代码地址:https://github.com/sinianshou/EGSwiftLearning

<think>好的,我需要回答用户关于数字通信中的零交叉符号同步算法的问题。首先,我需要确认自己对这一概念的理解是否准确。零交叉同步算法主要用于符号同步,也就是确定接收信号中符号的起始时刻,确保正确采样。它的核心思想应该是利用信号波形在符号转换时的过零点来进行时间同步。 接下来,我得回忆相关原理。在数字通信中,基带信号经过成形滤波器后,波形会在符号切换时产生过零点,尤其是在使用某些脉冲成形如Manchester编码或某些调制方式时。接收端检测这些过零点,可以估计符号的边界,从而调整采样时刻。这种方法可能适用于非归零码或其他特定编码方式,但需要具体分析适用场景。 然后,要考虑实现步骤。通常包括信号预处理(比如滤波)、过零点检测、相位误差计算和时钟调整。可能需要使用锁相环(PLL)或数字滤波器来跟踪和调整时钟相位。需要解释每个步骤的作用,比如过零点检测如何确定信号穿越零点的时刻,相位误差如何计算,以及如何反馈调整采样时钟。 还要讨论优缺点。优点可能是实现相对简单,尤其是在有明显过零点的情况下;缺点可能包括对噪声敏感,特别是在低信噪比时,过零点检测容易受到干扰,导致同步误差。此外,如果信号本身过零点不明显,这种方法可能不适用,比如某些全响应或部分响应系统。 应用场景方面,可能多见于有线通信、某些无线标准或特定编码方式中。例如,旧式的调制解调器或某些工业通信协议可能采用这种同步方法。需要举出具体例子,但需要确保准确性,不确定的话可能需要查证。 然后生成相关问题。根据常见的知识点,用户可能想了解与其他同步方法的比较(如早迟门同步)、性能影响因素、具体实现中的算法(比如如何检测过零点)、改进方法(如何抗噪声)等。要确保问题覆盖原理、实现、优化和应用。 最后,检查是否符合用户的要求,特别是LaTeX格式是否正确,引用标识是否添加。例如,在提到基带信号或锁相环时是否需要引用,但用户提供的示例中没有具体引用来源,可能只需按示例末尾添加标识,但这里可能没有实际引用内容,所以可能需要调整。 现在整理思路,确保结构清晰,分点回答,使用正确的格式,避免技术错误,并用中文表达。</think>### 零交叉(Zero-Crossing)符号同步算法 零交叉符号同步算法是数字通信中用于符号定时恢复的关键技术,通过检测接收信号波形的过零点(zero-crossing point)来估计符号边界,从而实现采样时刻的精确同步[^1]。 #### 核心原理 1. **信号过零点特性** 在基带传输中,若使用非归零码(NRZ)或特定脉冲成形(如升余弦滤波器),符号切换时信号波形会经过零点。例如,二进制相移键控(BPSK)信号在符号跳变时可能产生过零点。 2. **过零点检测** 接收端通过检测信号的过零点时刻,结合符号周期$T$,可推算符号的起始位置。若实际过零点与理想位置存在偏差$\Delta t$,则需调整采样时钟以消除定时误差。 #### 实现步骤 1. **信号预处理** 对接收信号进行带通滤波或匹配滤波,增强过零点的显著性。 2. **过零点检测** 使用比较器或差分算法识别信号从正到负(或负到正)的跳变点,例如: $$ s(t_i) \cdot s(t_{i+1}) < 0 \implies t_i \text{为过零点} $$ 3. **相位误差计算** 根据检测到的过零点与本地时钟的偏差,计算定时误差$e = t_{\text{actual}} - t_{\text{ideal}}$,并通过锁相环(PLL)或数字控制振荡器(NCO)调整采样时钟。 #### 优缺点分析 - **优点** - 实现简单,计算复杂度低; - 适用于高信噪比环境下的符号同步。 - **缺点** - 对噪声敏感,低信噪比时易产生误检测; - 依赖信号本身的过零点特性,部分调制方式(如QAM)不适用。 #### 应用场景 - **有线通信系统**:如以太网中的曼彻斯特编码; - **低频无线传输**:如RFID标签通信; - **工业控制网络**:如CAN总线[^1]。 ```python # 过零点检测示例代码 def zero_crossing_detect(signal): crossings = [] for i in range(1, len(signal)): if signal[i-1] * signal[i] < 0: crossings.append(i) return crossings ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值