#61 Rotate List

本文详细解析了链表旋转算法的实现过程,包括如何通过调整链表节点的next指针来实现链表的右旋转。文章提供了具体示例,如输入1->2->3->4->5->NULL, k=2时的输出为4->5->1->2->3->NULL,并附带了完整的代码实现。

Description

Given a linked list, rotate the list to the right by k places, where k is non-negative.

Examples

Example 1:

Input: 1->2->3->4->5->NULL, k = 2
Output: 4->5->1->2->3->NULL
Explanation:
rotate 1 steps to the right: 5->1->2->3->4->NULL
rotate 2 steps to the right: 4->5->1->2->3->NULL

Example 2:

Input: 0->1->2->NULL, k = 4
Output: 2->0->1->NULL
Explanation:
rotate 1 steps to the right: 2->0->1->NULL
rotate 2 steps to the right: 1->2->0->NULL
rotate 3 steps to the right: 0->1->2->NULL
rotate 4 steps to the right: 2->0->1->NULL

解题思路

首先第一步是要重新定位 kkk,因为可以循环,所以需要重置 kkk 的值,如对于一个长度为 555 的链表来说,k=2k = 2k=2k=7k = 7k=7 的效果是一样的。

那么在定位 kkk 的时候,由于需要用到链表长度,所以可以获得 nullnullnull 前最后一个节点。

一个长度为7的链表,向右移动5位,通过观察可以得到

转换前1234567
转换后3456712

关键点在于黄色标注的位置。

其中需要令 headnew=[3]head_{new} = [3]headnew=[3][7].next=headprevious[7].next = head_{previous}[7].next=headprevious[2].next=null[2].next = null[2].next=null

这几个位置也很好获得,[2][2][2] 的位置可以通过 length−klength - klengthk 获得,[3][3][3] 的位置可以通过 [2].next[2].next[2].next 获得, [7][7][7] 的位置可以通过遍历链表计算 lengthlengthlength 的时候获得

那么对于获得的节点,直接修改 nextnextnext 指针即可。

代码

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode rotateRight(ListNode head, int k) {
        if(head == null)
            return head;
        ListNode a, b, temp;
        a = head;
        b = head;
        int i, n;
        n = 0;
        while(a.next != null){
            n++;
            a = a.next;
        }
        n++;
        
        if((k % n == 0) || (n == 0))
            return head;
        
        k = (n - 1) - (k % n);
        for(i = 0; i < k; i++){
            b = b.next;
        }
        temp = b.next;
        
        a.next = head;
        b.next = null;
        
        return temp;
    }
}
#!/bin/sh # author: yuanhuihui # time: 2025/08/19 # file description: echo "file_check.sh start" ################################################################ ################ param init ################### ################################################################ CONFIG_FILE="/tplink/exe/data/monitor_file_check.cfg" LOG_FILE_1="/tplink/exe/data/controller_file1.log" LOG_FILE_2="/tplink/exe/data/controller_file2.log" SCAN_INTERVAL_DEF=600 LOG_LINES_DEF=10 CURRENT_LOG_LINES=0 CURRENT_LOG_FILE=$LOG_FILE_1 SCAN_INTERVAL=$SCAN_INTERVAL_DEF MAX_LOG_LINES=$LOG_LINES_DEF echo "func convert_to_bytes statement" convert_to_bytes(){ local size=$1 local unit="${size: -1}" local num="${size%?}" case "$unit" in k|K) echo $((num * 1024));; m|M) echo $((num * 1024 * 1024));; g|G) echo $((num * 1024 * 1024 * 1024));; *) echo "$size";; esac } ################################################################ ################ test ################### ################################################################ # clear log file echo "func clear_file statement" clear_file() { local file_path="$1" if [ -f "$file_path" ]; then :> "$file_path" echo "Cleared contents of file: $file_path" else echo "File does not exist: $file_path" fi } echo "func create_file_if_not_exists statement" create_file_if_not_exists() { local file_path="$1" # 获取传入的第一个参数,即文件路径 # 获取文件所在目录 local dir_path=$(dirname "$file_path") # 检查目录是否存在,如果不存在则创建 if [ ! -d "$dir_path" ]; then mkdir -p "$dir_path" echo "dir $dir_path create" fi # 检查文件是否存在 if [ ! -f "$file_path" ]; then touch "$file_path" echo "file $file_path create。" else echo "file $file_path exist" fi } echo "check file existence" # 检查文件是否存在 create_file_if_not_exists $LOG_FILE_1 create_file_if_not_exists $LOG_FILE_2 echo "clear file" clear_file "$LOG_FILE_1" clear_file "$LOG_FILE_2" # files to be handlered files=( "/tplink/exe/data/fileList/file1 3k" "/tplink/exe/data/fileList/file2 3k" "/tplink/exe/data/fileList/file3 3k" ) echo "traverse file configuration" # traverse file configuration for entry in "${files[@]}"; do # get file name and limit size output_file=$(echo "$entry" | awk &#39;{print $1}&#39;) input_size=$(echo "$entry" | awk &#39;{print $2}&#39;) # create target path when not exist mkdir -p "$(dirname "$output_file")" # get number byte_count=$(convert_to_bytes "$input_size") # format check if ! [[ "$byte_count" =~ ^[0-9]+$ ]]; then echo "ERROR: invalid format &#39;$input_size&#39; skip &#39;$output_file&#39;" continue fi # wirte random data to file dd if=/dev/urandom of="$output_file" bs=1 count="$byte_count" 2>/dev/null # debug echo "write data to &#39;$output_file&#39; $byte_count Bytes" done ################################################################ ################ get global config ################### ################################################################ # get global config get_config_value() { local section="$1" local key="$2" awk -v section="$section" -v key="$key" &#39; BEGIN { in_section = 0; } $1 == section { in_section = 1; next } in_section && $1 == key { print $3; exit } &#39; "$CONFIG_FILE" } # if [ ! -f "$CONFIG_FILE" ]; then log "ERROR" "Config File $CONFIG_FILE not exist" exit 1 fi SCAN_INTERVAL=$(get_config_value "[global]" "check_interval") MAX_LOG_LINES=$(get_config_value "[global]" "max_log_lines") # if [ -z "$SCAN_INTERVAL" ]; then SCAN_INTERVAL="$SCAN_INTERVAL_DEF" log "WARN" "Using default check_interval: $SCAN_INTERVAL seconds" fi if [ -z "$MAX_LOG_LINES" ]; then MAX_LOG_LINES="$LOG_LINES_DEF" log "WARN" "Using default log lines limit: $MAX_LOG_LINES " fi echo "SCAN_INTERVAL = $SCAN_INTERVAL" echo "MAX_LOG_LINES = $MAX_LOG_LINES" ################################################################ ################ get file list ################### ################################################################ # traverse file list mapfile -t files < <(awk &#39; BEGIN { in_file = 0; } $1 == "[file]" { in_file = 1; next; } /^\$$[a-zA-Z]/ { in_file = 0; } in_file && $1 == "filename" { gsub(/[[:space:]]*/, "", $3); split($3, a, ":"); print a[1] "|" a[2]; } &#39; "$CONFIG_FILE") # file param init file_name=() file_size=() # get elemments in file list for line in "${files[@]}"; do IFS=&#39;|&#39; read -r name size <<< "$line" file_name+=("$name") file_size+=("$size") done # debug echo "file configuration:" for i in "${!file_name[@]}"; do echo "filename: ${file_name[$i]}, limit: ${file_size[$i]}" done ################################################################ ################ log function ################### ################################################################ rotate_log_file() { if [ "$CURRENT_LOG_FILE" = "$LOG_FILE_1" ]; then CURRENT_LOG_FILE=$LOG_FILE_2 else CURRENT_LOG_FILE=$LOG_FILE_1 fi > "$CURRENT_LOG_FILE" # clear file log CURRENT_LOG_LINES=0 } # log(){ local level=$1 local message=$2 local timestamp=$(date "+%Y-%m-%d %H:%M:%S") if (( CURRENT_LOG_LINES >= MAX_LOG_LINES )); then echo "CURRENT_LOG_LINES = $CURRENT_LOG_LINES, exceed MAX_LOG_LINES = $MAX_LOG_LINES, change log file" rotate_log_file fi CURRENT_LOG_LINES=$((CURRENT_LOG_LINES + 1)) echo "[$timestamp][$level]$message" >> "$CURRENT_LOG_FILE" } ################################################################ ################ scan file list ################### ################################################################ while true; do log "INFO" "start file check cycle..." for i in "${!file_name[@]}"; do declare path="${file_name[$i]}" declare limit_str="${file_size[$i]}" declare limit_bytes=$(convert_to_bytes "$limit_str") if [[ -e "$path" ]]; then if [[ -f "$path" ]]; then declare file_size_bytes=$(stat -c%s "$path") if (( file_size_bytes > limit_bytes )); then > "$path" # clear file content log "INFO" "file &#39;$path&#39; size $file_size_bytes Byte, exceed limit $limit_str" echo "INFO" "file &#39;$path&#39; size $file_size_bytes Byte, exceed limit $limit_str" fi else log "[WARN" "file &#39;$path&#39; is not regular file" echo "[WARN" "file &#39;$path&#39; is not regular file" fi else log "[WARN" "file &#39;$path&#39; not exist" echo "[WARN" "file &#39;$path&#39; not exist" fi done # wait for net scan sleep "$SCAN_INTERVAL" done
最新发布
08-23
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值