2.8 Loop Detection

本文介绍了一种使用快慢指针来检测链表中是否存在循环的方法,并详细解释了其背后的数学原理。通过该方法,我们不仅能判断链表是否有环,还能找到环的起始节点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

For this problem, we have to do a little math deduction:
let L1 indicates the distance between start point and head; L2 indicates the distance between start point and meet point; C indicates the length of cycle;
For fast pointer, it goes L1 + n*C + L2 before meet with slow pointer. And for slow pointer, it goes L1 + L2. We know the speed relationship between slow and fast is that

fast=2slow
Thus we have
L1=nCL2
Which gives us a conclusion: the distance between head and start equals to the distance between meet point to start point along forward movement.
    ListNode *detectCycle(ListNode *head) {
        // write your code here
        if(!head || !head->next) return NULL;
        ListNode *fast = head;
        ListNode *slow = head;
        ListNode *start = head;
        while(fast->next && fast->next->next){
            fast = fast->next->next;
            slow = slow->next;
            if(fast == slow){
                while (slow != start){
                    slow = slow->next;
                    start = start->next;
                }
                return start;
             }
        }
        return NULL;
    }
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Modified for HackRF received.raw processing % % Last Revision: 2023-12-01 % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% clc; close all; clear all; %% HackRF parameters %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% GAIN = 40; % Matches HackRF gain setting F_ADC = 2e6; % 2 MS/s (from HackRF command) DEC = 1; Fs = F_ADC/DEC; Ts = 1/Fs; %% Symbol parameters %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Tsymbol = 2.8e-3; % Symbol duration Tbit = Tsymbol*2; % Bit duration over = round(Tsymbol/Ts); % Oversampling factor newover = 10; % Downsample factor %% Tag Packet parameters %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% preamble_length = 10; id_length = 2; util_length = 1; codeword_length = 10; dummybit = 1; total_packet_length = id_length + preamble_length + util_length + codeword_length + dummybit; total_packet_duration = total_packet_length*Tbit; % Preamble in FM0 format preamble_symbols = [1 1 0 1 0 0 1 0 1 1 0 1 0 0 1 1 0 0 1 1]; preamble = preamble_symbols; preamble_neg = -1 * preamble_symbols; % Known test data fixedata = [0 0 1 1 1 1 0 0 0 1 0 1]; fixedpacketdata = [0 1 0 0 1 1 1 1 0 0 0 1 1]; % id + sensor_id + fixedata %% Signal Processing Setup framelength = 3; % Capture window = 3*packet_length t_sampling = framelength * total_packet_duration; N_samples = round(Fs * t_sampling); %% File Input Setup filename = 'received.raw'; % HackRF output file fileinfo = dir(filename); file_size = fileinfo.bytes; samples_per_frame = 2 * N_samples; % I+Q samples num_frames = floor(file_size / (2 * samples_per_frame)); % 2 bytes per sample (I and Q) %% Decoder Variables correct_packets = 0; error_packets = 0; BER_sum = []; packets = 0; %% Orthogonal pulses for detection D1_ups = zeros(1, newover*2); D1_ups(1:newover) = 1; D1_ups(newover+1:newover*2) = -1; D2_ups = zeros(1, newover*2); D2_ups(1:newover) = -1; D2_ups(newover+1:newover*2) = 1; %% Main Processing Loop fid = fopen(filename, 'rb'); for frame_idx = 1:num_frames % Read raw I/Q data (8-bit signed format) raw_data = fread(fid, 2*samples_per_frame, 'int8'); if isempty(raw_data) break; end % Convert to complex samples I = raw_data(1:2:end); Q = raw_data(2:2:end); x = I + 1j*Q; x = x / 128.0; % Normalize to [-1, 1] packets = packets + 1; fprintf('Processing packet %d/%d\n', packets, num_frames); %% Signal Processing Chain % 1. Power detection abstream = abs(x).^2; % 2. Matched filtering matcheds = ones(round(Tsymbol/Ts), 1); dataconv = conv(abstream, matcheds); % 3. Downsample total_env_ds = dataconv(1:over/newover:end); total_envelope = total_env_ds(newover+1:end-newover+1); total_envelope = total_envelope - mean(total_envelope); %% Packet Detection % Create preamble template preample_neover = upsample(preamble, newover); % Correlation-based detection corrsync_out = xcorr(preample_neover, total_envelope); [m, ind] = max(corrsync_out); start = length(total_envelope) - ind; % Validate packet start position if start <= 0 || (start + total_packet_length*2*newover) > length(total_envelope) fprintf('Invalid packet position. Skipping.\n'); continue; end %% FM0 Decoding shifted_sync_signal = total_envelope(start:start + total_packet_length*2*newover - 1); bits_FM0 = []; decision_bits = []; % Symbol decoding for xi = 1:newover*2:length(shifted_sync_signal)-newover*2 sample = shifted_sync_signal(xi:xi+newover*2-1); sumD1 = sum(D1_ups .* sample'); sumD2 = sum(D2_ups .* sample'); bits_FM0(end+1) = sumD1 > sumD2; end % FM0 differential decoding for indx = 2:length(bits_FM0) decision_bits(end+1) = bits_FM0(indx) ~= bits_FM0(indx-1); end %% Packet Validation if length(decision_bits) >= length(fixedpacketdata) packet_est = decision_bits(1:length(fixedpacketdata)); if isequal(packet_est, fixedpacketdata) fprintf('Packet Correct!\n'); correct_packets = correct_packets + 1; else fprintf('Packet Error\n'); error_packets = error_packets + 1; BER_sum(end+1) = sum(xor(packet_est, fixedpacketdata)); end else fprintf('Incomplete packet. Expected %d bits, got %d\n',... length(fixedpacketdata), length(decision_bits)); end end fclose(fid); %% Performance Report fprintf('\n===== Decoding Results =====\n'); fprintf('Total packets processed: %d\n', packets); fprintf('Correct packets: %d (%.1f%%)\n', correct_packets, 100*correct_packets/packets); fprintf('Errored packets: %d\n', error_packets); if error_packets > 0 fprintf('Average BER: %.4f\n', mean(BER_sum/length(fixedpacketdata))); end%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Spiros Daskalakis % % last Revision 11/7/2017 % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% clc; close all; clear all; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %pause(6) %wait six sec %% RTL SDR parameters %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% GAIN=-15; F_ADC = 1e6; %1 MS/s DEC = 1; Fs = F_ADC/DEC; Ts = 1/Fs; %% Sympol parameters %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Tsymbol = 2.8e-3; % put the Duration (T) or the smallest Sympol of the bitstream % put 0.990e-3 => for 500 bps % put 500e-6 => for 1 kbps % put 202e-6 = for 2 kbps (try 198) Tbit=Tsymbol*2; % Datarate= 1/Tbit => For 500 us: 1 kbps over = round(Tsymbol/Ts); % Oversampling factor newover = 10; % Downsample factor %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Tag Packet parameters %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %Bitstreams length preamble_length=10; % NoFM0_prample=[1 0 1 0 1 0 1 1 1 1]; id_length=2; % NoFM0_ID=[0 1]; util_length=1; % NoFM0_util=[0 1]; codeword_length=10; % NoFM0_DATA=[0 0 1 1 1 1 0 0 0 1 0 1]; dummybit=1; %put a dummy bit at the end of packet bitstream for better reception %%% total_packet_length=id_length+preamble_length+util_length+codeword_length+dummybit; total_packet_duration=total_packet_length*Tbit; preamble_duration=preamble_length*Tbit; % Preamble in FM0 format with symbols (not bits). preamble_symbols=[1 1 0 1 0 0 1 0 1 1 0 1 0 0 1 1 0 0 1 1]; preamble = preamble_symbols; %try (2*preamble_bits-1)=> same result preamble_neg=-1*preamble_symbols; preamble_neg_pos=2*preamble_symbols-1; % bitstreams with Data and packet data contained in the packet=>for validation perposes fixedata=[0 0 1 1 1 1 0 0 0 1 0 1]; fixedpacketdata=[0 1 0 0 1 1 1 1 0 0 0 1 1]; % id + sensor_id + fixedata %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Sigmal Prosesing Variables % For FFT plots (not used) Resolution = 1; % in Hz N_F = Fs/Resolution; F_axis = -Fs/2:Fs/N_F:Fs/2-Fs/N_F; %% Capture Window Parameters framelength=3; %Window=3*packet_length t_sampling = framelength*total_packet_duration; % Sampling time frame (seconds). N_samples = round(Fs*t_sampling); %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Import Datasets fi = fopen('myfifo', 'rb'); t = 0:Ts:t_sampling-Ts; HIST_SIZE =1200; dataset=[]; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Debug Print variables => activate and deactive the plots DEBUG_en1=0; DEBUG_en2=1; DEBUG_en3=0; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Decoder General variables correct_packets=0; error_packets=0; cut_packets=0; negative_starts1=0; negative_starts2=0; droped_packets=0; pos=1; FLIPPED=0; packets = 1; counter=0; nopacket_ind=0; nodroped_packets=0; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Decoder FM0 vectors bits_FM0_2sd_wayB=[]; decision_bits_B=[]; BER_sum=[]; infomatr=[]; errorind=[]; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Orthogonal pulces for detection %D1 D1_ups=zeros(1,newover*2); D1_ups(1:newover)=1; D1_ups(newover+1:newover*2)=-1; %D2 D2_ups=zeros(1,newover*2); D2_ups(1:newover)=-1; D2_ups(newover+1:newover*2)=1; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ENERGYTHRESS=0; ENERGYTHRESS1=0; %dataset= NaN*ones(0,HIST_SIZE); dataset= []; while (1) x = fread(fi, 2*N_samples, 'float32'); % get samples (*2 for I-Q) x = x(1:2:end) + j*x(2:2:end); % deinterleaving counter = counter + 1; % dataset= [dataset ; x]; % delay every two windows || ===> capture__delay(duration=packet_window)__capture__delay__...... if ~mod(counter, 2) packets = packets + 1; fprintf('Packet=%d|\n',packets) %dataset= [dataset ; x]; %% Absolute operation removes the unknown CFO abstream=abs(x).^2; %% Matched filtering matcheds=ones(round(Tsymbol/Ts),1); % the pulse of matched filter has duration Tsymbol dataconv=conv(abstream,matcheds); % aply the filter with convolution %% Downsample same prosedure total_env_ds = dataconv(1:over/newover:end); %% by factor of 10 to reduce the computational complexity %% Time sync of downsample total_envelope = total_env_ds(newover+1:end-newover+1); % total_env_ds(newover+1:end-newover+1); %% remove the DC offset total_envelope=total_envelope-mean(total_env_ds); %% Reject windows if the energy is not much % Calculate the energy in the packet. If the energy is less than a threshold, discard packet. energy= sum(total_envelope.^2); maxpoint= max(abs(total_envelope)); %% Flip the packet if its nessesarry %% Position estimation of packet with packet's energy synchronization for k=1:1: length(total_envelope)-(total_packet_length*2*newover)+1 energy_synq(k)=sum(abs(total_envelope(k : k+total_packet_length*2*newover-1)).^2); end % find the starting point of packet [energy_sinq_max energy_sinq_ind]=max(energy_synq); %% Print Plots if DEBUG_en1==1; time_axis= 0:Ts:Ts*length(abstream)-Ts; %same as xaxis_m= (1: length(abstream))*Ts Captured signal time axis. % fft x_fft = fftshift(fft(x, N_F)); F_sensor_est_power=10*log10((abs(x_fft).^2)*Ts/50*1e3)-15; figure(1); subplot(2, 1, 1); plot(time_axis,abstream); title('Time Domain') xlabel('Time (Sec)'); subplot(2, 1, 2); plot(F_axis/1000000, F_sensor_est_power); title('Frequency Domain') xlabel('Frequency (MHz)'); drawnow; end if DEBUG_en2==1; figure(3); time_axis= 0:Ts:Ts*length(abstream)-Ts; time_comv=0:Ts:Ts*length(dataconv)-Ts; subplot(2, 1, 1); plot(dataconv); title('Matched-filtered' ,'FontSize',14 ) xlabel('Time (Sec)', 'FontSize',12, 'FontWeight','bold'); ylabel('Amplitude', 'FontSize',12, 'FontWeight','bold'); grid on; subplot(2, 1, 2); plot(total_envelope); title('FLIPPED DOWNSAMPLED') drawnow; end if DEBUG_en3==1; figure(5); plot(total_envelope); xlabel('Time (Sec)', 'FontSize',12, 'FontWeight','bold'); ylabel('Amplitude', 'FontSize',12, 'FontWeight','bold'); grid on; drawnow; end %% dc zero offser %% Assume symbol synchronization, which can be implemented using correlation with a sequence of known bits in the preamble % comparison of the detected preamble bits with the a priori known bit sequence %convert the header to a time series for the specific sampling frequency and bit duration. %% create the preamble neover format preample_neover=upsample(preamble, newover); preample_neg_neover=upsample(preamble_neg, newover); %% Sync via ENERGY for k=1:1: length(total_envelope)- (total_packet_length*2*newover)+1 energy_synq(k)=sum(abs(total_envelope(k : k+total_packet_length*2*newover-1)).^2); end [energy_sinq_max energy_sinq_ind]=max(energy_synq); sumxor=0; pointer1=energy_sinq_ind-total_packet_length*2*newover; % if pointer1<=0 || energy <= ENERGYTHRESS/3 % negative_starts2=negative_starts2+1; % disp 'Negative start_2'; % continue; % end %% Sync via preamble correlation corrsync_out = xcorr(preample_neover, total_envelope); corrsync_out_neg = xcorr(preample_neg_neover, total_envelope); [m ind] = max(corrsync_out); [m_neg ind_neg] = max(corrsync_out_neg); %notice that correlation produces a 1x(2L-1) vector, so index must be shifted. %the following operation points to the "start" of the packet. if (m < m_neg) start = length(total_envelope)-ind_neg; else start = length(total_envelope)-ind; end if(start <= 0) negative_starts1 = negative_starts1 + 1; disp 'Negative start_1'; continue; %% Check if the detected packet is cut in the middle. elseif start+((total_packet_length)*2)*newover > length(total_envelope) cut_packets = cut_packets + 1; disp 'Packet cut in the middle!'; continue; end shifted_sync_signal_B=total_envelope(start+length(preample_neover)-newover-1: start+total_packet_length*2*newover); for xi=1:newover*2: length(shifted_sync_signal_B)-newover*2 sample2=shifted_sync_signal_B(xi: xi+newover*2-1); sumD1_ups=sum(D1_ups.*sample2'); sumD2_ups=sum(D2_ups.*sample2'); if (sumD1_ups > sumD2_ups) bits_FM0_2sd_wayB=[bits_FM0_2sd_wayB, 1]; else bits_FM0_2sd_wayB=[bits_FM0_2sd_wayB, 0]; end end jim=1; for indx=2:1:length(bits_FM0_2sd_wayB) if bits_FM0_2sd_wayB(indx) == bits_FM0_2sd_wayB(indx-1) decision_bits_B(jim)=0; else decision_bits_B(jim)=1; end jim=jim+1; end id_est_B = decision_bits_B(1: id_length); sensor_id_est_B = decision_bits_B(id_length + 1: id_length + util_length); data_bits_es_B = decision_bits_B(id_length+util_length + 1:end); if isequal(decision_bits_B, fixedpacketdata) disp 'Packet Correct !!!!!!!!!!!!!!!!!!!!!!!!!'; ENERGYTHRESS=energy; ENERGYTHRESS1=maxpoint; correct_packets=correct_packets+1; else disp 'Packet WRONGGGG-------------------------------------------------'; errorind=[ errorind, packets ]; error_packets=error_packets+1; BER_sum(error_packets) = sum(xor(decision_bits_B,fixedpacketdata)); end bits_FM0_2sd_wayB=[]; decision_bits_B=[]; end if(mod(packets,HIST_SIZE) ==0) infomatr(1)=correct_packets; infomatr(2)=error_packets; infomatr(3)=negative_starts1+negative_starts2; infomatr(4)=cut_packets; infomatr(5)=error_packets /(correct_packets+error_packets); infomatr(6)= sum(BER_sum); infomatr(7)= sum(BER_sum)/((correct_packets+error_packets)*length(fixedpacketdata)); fprintf('Corecct Packets=%d|Packet Error=%d\n',correct_packets, error_packets) fprintf('Negative Starts=%d|Cut Packets=%d\n', negative_starts1, cut_packets) fprintf('Negative Starts2=%d\n', negative_starts2) %PER is the number of incorrectly received data packets divided by the total number of received packets. fprintf('Packet Error Rate=%d\n', error_packets / (correct_packets+error_packets)) %fprintf('Bit error rate mean(BER)=%d\n', mean(BER_int)) fprintf('Bit error rate (BER)=%d\n', sum(BER_sum)/((correct_packets+error_packets)*length(fixedpacketdata))) % rootname = 'FM_amb_500us_15G_95_8MHz_15000_pack_80_meters'; % Root filename % data = clock; % filename = [rootname, num2str(data(4)) num2str(data(5))... % num2str(data(2)) num2str(data(3)) num2str(data(1))]; %save(filename,'dataset') % save('FM_amb_95_8_Mhz_200_pack_2','dataset') save('results_FM_amb_1ms_review_1500_pakets_min55_dbm_geb_3','infomatr') return; end end 这两个程序有什么不同
最新发布
07-30
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值