leetcode 93 复原IP地址 回溯

该篇文章描述了一个编程问题,要求从给定的数字字符串中生成所有有效的IP地址,每个IP地址由四个整数组成,且不能含有前导0。提供了C语言的解决方案,采用了深度优先搜索(DFS)策略。
摘要由CSDN通过智能技术生成

有效 IP 地址 正好由四个整数(每个整数位于 0 到 255 之间组成,且不能含有前导 0),整数之间用 '.' 分隔。

  • 例如:"0.1.2.201" 和 "192.168.1.1" 是 有效 IP 地址,但是 "0.011.255.245""192.168.1.312" 和 "192.168@1.1" 是 无效 IP 地址。

给定一个只包含数字的字符串 s ,用以表示一个 IP 地址,返回所有可能的有效 IP 地址,这些地址可以通过在 s 中插入 '.' 来形成。你 不能 重新排序或删除 s 中的任何数字。你可以按 任何 顺序返回答案。

示例 1:

输入:s = "25525511135"
输出:["255.255.11.135","255.255.111.35"]

代码随想录:

#include <stdio.h>
#include <stdlib.h>
#include "string.h"
int path[100];
int top=0;
int segments[3];
int isValid(char *s,int start, int end) {
    if (start>end)
        return 0;
    if (s[start] == '0' && start != end)
        return 0;
    int num=0;
    for (int i = start; i <= end; ++i) {
        if (s[i] > '9' || s[i] < '0')
            return 0;
        num = num*10 + (s[i] - '0');
        if (num > 255){
            return 0;
        }
    }
    return 1;
}
void dfs(char *s,int startIndex,int pointNum)
{
    if(pointNum==3){
        if (isValid(s,startIndex,strlen(s)-1)){
//            char* tempString = (char*)malloc(sizeof(char) * strlen(s) + 4);
            int j;
            //记录添加字符时tempString的下标
            int count = 0;
            //记录添加字符时'.'的使用数量
            int count1 = 0;
            for(j = 0; j < strlen(s); j++) {
                path[count++] = s[j];
                //若'.'的使用数量小于3且当前下标等于'.'下标,添加'.'到数组
                if(count1 < 3 && j == segments[count1]) {
                    path[count++] = '.';
                    count1++;
                }
            }
            for (int j = 0; j < strlen(s)+pointNum; ++j) {
                if (path[j] >= '0' && path[j] <= '9')
                    printf("%d",path[j]);
                else
                    printf("%c",path[j]);
            }
            printf("\n");
//            path[count] = 0;
            //扩容result数组
//            path[top++] = tempString;
        }
        return ;
    }
    for (int i = startIndex; i < strlen(s); ++i) {
        if (isValid(s,startIndex,i)){
            segments[pointNum]=i;
            dfs(s,i+1,pointNum+1);
        }
        else
            break;
    }
}
int main()
{
    char *s="25525511135";
    dfs(s,3,0);
    return 0;
}

leetcode官网:

#define SEG_COUNT 4
int segments[SEG_COUNT];
char** ans;
int ans_len;

void dfs(char* s, int segId, int segStart) {
    // 如果找到了 4 段 IP 地址并且遍历完了字符串,那么就是一种答案
    int len_s = strlen(s);
    if (segId == SEG_COUNT) {
        if (segStart == len_s) {
            char* ipAddr = (char*)malloc(sizeof(char) * (len_s + 4));
            int add = 0;
            for (int i = 0; i < SEG_COUNT; ++i) {
                int number = segments[i];
                if (number >= 100) {
                    ipAddr[add++] = number / 100 + '0';
                }
                if (number >= 10) {
                    ipAddr[add++] = number % 100 / 10 + '0';
                }
                ipAddr[add++] = number % 10 + '0';
                if (i != SEG_COUNT - 1) {
                    ipAddr[add++] = '.';
                }
            }
            ipAddr[add] = 0;
            ans = realloc(ans, sizeof(char*) * (ans_len + 1));
            ans[ans_len++] = ipAddr;
        }
        return;
    }

    // 如果还没有找到 4 段 IP 地址就已经遍历完了字符串,那么提前回溯
    if (segStart == len_s) {
        return;
    }

    // 由于不能有前导零,如果当前数字为 0,那么这一段 IP 地址只能为 0
    if (s[segStart] == '0') {
        segments[segId] = 0;
        dfs(s, segId + 1, segStart + 1);
        return;
    }

    // 一般情况,枚举每一种可能性并递归
    int addr = 0;
    for (int segEnd = segStart; segEnd < len_s; ++segEnd) {
        addr = addr * 10 + (s[segEnd] - '0');
        if (addr > 0 && addr <= 0xFF) {
            segments[segId] = addr;
            dfs(s, segId + 1, segEnd + 1);
        } else {
            break;
        }
    }
}

char** restoreIpAddresses(char* s, int* returnSize) {
    ans = (char**)malloc(0);
    ans_len = 0;
    dfs(s, 0, 0);
    (*returnSize) = ans_len;
    return ans;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值