首页 > 编程语言 >每日算法 230303

每日算法 230303

时间:2023-03-03 23:23:11浏览次数:49  
标签:gta String int 每日 算法 names ans 230303 name

每日算法 230303

题目

1487. 保证文件名唯一

给你一个长度为 n 的字符串数组 names 。你将会在文件系统中创建 n 个文件夹:在第 i 分钟,新建名为 names[i] 的文件夹。

由于两个文件 不能 共享相同的文件名,因此如果新建文件夹使用的文件名已经被占用,系统会以 (k) 的形式为新文件夹的文件名添加后缀,其中 k 是能保证文件名唯一的 最小正整数

返回长度为 n 的字符串数组,其中 ans[i] 是创建第 i 个文件夹时系统分配给该文件夹的实际名称。

示例 1:

输入:names = ["pes","fifa","gta","pes(2019)"]
输出:["pes","fifa","gta","pes(2019)"]
解释:文件系统将会这样创建文件名:
"pes" --> 之前未分配,仍为 "pes"
"fifa" --> 之前未分配,仍为 "fifa"
"gta" --> 之前未分配,仍为 "gta"
"pes(2019)" --> 之前未分配,仍为 "pes(2019)"
示例 2:

输入:names = ["gta","gta(1)","gta","avalon"]
输出:["gta","gta(1)","gta(2)","avalon"]
解释:文件系统将会这样创建文件名:
"gta" --> 之前未分配,仍为 "gta"
"gta(1)" --> 之前未分配,仍为 "gta(1)"
"gta" --> 文件名被占用,系统为该名称添加后缀 (k),由于 "gta(1)" 也被占用,所以 k = 2 。实际创建的文件名为 "gta(2)" 。
"avalon" --> 之前未分配,仍为 "avalon"
示例 3:

输入:names = ["onepiece","onepiece(1)","onepiece(2)","onepiece(3)","onepiece"]
输出:["onepiece","onepiece(1)","onepiece(2)","onepiece(3)","onepiece(4)"]
解释:当创建最后一个文件夹时,最小的正有效 k 为 4 ,文件名变为 "onepiece(4)"。
示例 4:

输入:names = ["wano","wano","wano","wano"]
输出:["wano","wano(1)","wano(2)","wano(3)"]
解释:每次创建文件夹 "wano" 时,只需增加后缀中 k 的值即可。
示例 5:

输入:names = ["kaido","kaido(1)","kaido","kaido(1)"]
输出:["kaido","kaido(1)","kaido(2)","kaido(1)(1)"]
解释:注意,如果含后缀文件名被占用,那么系统也会按规则在名称后添加新的后缀 (k) 。

提示:

  • 1 <= names.length <= 5 * 10^4
  • 1 <= names[i].length <= 20
  • names[i] 由小写英文字母、数字和/或圆括号组成。

来源:

力扣(LeetCode)

思路

​ 将给出的字符串数组names赋值给新建数组ans ,循环赋值时判断是否和已经赋值过的ans数组内的文件名相同,如果相同后面加(k),k为已经赋值过的相同文件名再判断+1全部完成之后返回ans数组。难点可能在于如何判断name(n)这个文件名的数目,即如何

解题

第一版大概是这样

class Solution {
    public String[] getFolderNames(String[] names){

        //返回的字符串数组
        String[] ans = new String[names.length];

        //循环判断
        for (int i = 0; i < names.length; i++) {

            //用以判断ans数组中是否存在相同元素
            boolean flag = false;

            //遍历ans数组
            for (int j = 0; j < ans.length; j++) {

                //判断ans数组中是否存在相同名称
                if (names[i].equals(ans[j])){
                    flag = true;
                    //增加一个flag,相同则为true
                    break;

                }
            }

            //如果存在相同名称则再判断后面的k为多少
            //再次遍历ans数组
            if(flag) {
                a:
                for (int k = 1; ; k++) {

                    for (int j = 0; j < ans.length; j++) {

                        //判断k
                        if ((names[i] + "(" + k + ")").equals(ans[j])) {
                            continue a;
                        } else {

                        }
                    }
                    ans[i] = names[i] + "(" + k + ")";
                    break;
                }
            } else {
                ans[i] = names[i];
            }

        }

        return ans;
    }
}

填入测试用例全部准确,但提交时却显示超出时间限制。

可能是判断k值时循环次数太多导致,因此我打算修改此段代码,思路大概是只循环一次然后提取和name(n)格式一致的,存放入可变数组array中,然后再遍历array数组,判断k值。因为ans数组的长度是由names的长度决定,所以先尝试让循环到null值结束。

package com.tyrantblue.solution;

import java.util.ArrayList;

public class Test05 {
    public static void main(String[] args) {

        String[] names = {"r","f","r","z","r"};
        Solution05 solution05 = new Solution05();
        for (int i = 0; i < names.length; i++) {
            System.out.println(solution05.getFolderNames(names)[i]);
        }

    }
}

class Solution05 {
    public String[] getFolderNames(String[] names){

        //返回的字符串数组
        String[] ans = new String[names.length];

        //循环判断
        for (int i = 0; i < names.length; i++) {

            //声明一个可变数组arrays用于存放name(n)
            ArrayList<String> arrays = new ArrayList<>();

            //用以判断ans数组中是否存在相同元素
            boolean flag = false;

            //遍历ans数组
            for (int j = 0; j < ans.length; j++) {

                //让循环到ans的末尾结束
                if (ans[j] == null) {
                    break;
                }
                //判断ans数组中是否存在相同名称
                if (names[i].equals(ans[j])){

                    //增加一个flag,相同则为true
                    flag = true;
                    }
                //从ans中提取出名字为name或者name(n)的
                for (int i1 = 0; i1 < i; i1++) {
                    if ((names[i] + "(" + (i1+1) + ")").equals(ans[j])){
                        arrays.add(ans[j]) ;

                }


                }
            }

            //如果存在相同名称则再判断后面的k为多少
            //再次遍历ans数组
            if(flag) {
                a:
                for (int k = 1; ; k++) {

                    for (int j = 0; j < arrays.size(); j++) {

                        //让循环到ans的末尾结束
                        if (arrays.get(j) == null) {
                            break;
                        }

                        //判断k
                        if ((names[i] + "(" + k + ")").equals(arrays.get(j))) {
                            continue a;
                        }
                    }
                    ans[i] = names[i] + "(" + k + ")";
                    break;
                }
            } else {
                ans[i] = names[i];
            }

        }

        return ans;
    }
}

还是超出时间限制。

官方的参考答案如下:

class Solution {
    public String[] getFolderNames(String[] names) {
        Map<String, Integer> index = new HashMap<String, Integer>();
        int n = names.length;
        String[] res = new String[n];
        for (int i = 0; i < n; i++) {
            String name = names[i];
            if (!index.containsKey(name)) {
                res[i] = name;
                index.put(name, 1);
            } else {
                int k = index.get(name);
                while (index.containsKey(addSuffix(name, k))) {
                    k++;
                }
                res[i] = addSuffix(name, k);
                index.put(name, k + 1);
                index.put(addSuffix(name, k), 1);
            }
        }
        return res;
    }

    public String addSuffix(String name, int k) {
        return name + "(" + k + ")";
    }
}

总结

​ 官方答案和评论区的大家大部分都使用了哈希表,但是我还不会,也没怎么看懂,等之后学习了哈希表再来看这道题应该会有所收获。

标签:gta,String,int,每日,算法,names,ans,230303,name
From: https://www.cnblogs.com/tyrantblue/p/17177340.html

相关文章

  • java学习日记20230303-基本数据类型转换
    自动类型转换java程序在进行运算和赋值时,精度小的类型自动转化为精度大的类型,这个就是自动类型转化数据类型按照精度大小排序char-int-long-float-doublebyte-short-in......
  • JVM系统优化实践(7):垃圾回收器与垃圾回收算法
    您好,我是湘王,这是我的51CTO博客,欢迎您来,欢迎您再来~上回说到了年轻代、老年代与数据计算的一个案例。接下来就先讲一讲年轻代和老年代的两个垃圾回收器:ParNew和CMS。和Serial......
  • 每日打卡
    MySQL表的增删改查(基础)1.新增(Create)1.1单行数据+全列插入1.2多行数据+指定列2.查询(Retrieve)2.1全列查询2.2指定列查询2.3查询字段为表达式2.4别名2.5去重......
  • Android学习-每日打卡APP-进展
    今天课比较多,但是还是要抽出时间写安卓,又有了一些小进展,将数据库的部分代码写了出来可以参考一下packagecom.example.clockappliction;importandroid.content.Conte......
  • 算法基础1.3.3高精度乘法
    前言先看高精度加法的文章,如果没有看,我把高精度加法文章中的总结前言放到这里该文章探讨的高精度代指C++中极大整数的计算,不是浮点数(y总说那个少见,不讲)。这个问题只在C......
  • 2022.3.3每日总结
    HashSet基于HashMap来实现的,是一个不允许有重复元素的集合。HashSet允许有null值。HashSet是无序的,即不会记录插入的顺序。HashSet不是线程安全的,如果多个线程......
  • 每日总结 3.3
    今天学习了数据的添加,和本地日期的获取。<?xmlversion="1.0"encoding="utf-8"?><LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"......
  • 每日总结
    今天练习了数据库的添加,学习了日期的获取packagecom.example.meiri;importandroidx.appcompat.app.AppCompatActivity;importandroid.content.Intent;importand......
  • 每日总结-23.3.3
    Android中数据库的创建•数据库类:SQLiteDatabase•数据库帮助类:SQLiteOpenHelper方法一•db=SQLiteDatabase.openOrCreateDatabase(DATABASE_NAME,Context.MODE_PRI......
  • 每日总结(10)
    所用时间:晚上两个小时代码:71博客:1知识点:     储存;1/SharedDreferences;(1)共享参数使用场景2/SQLiter(1)排序(2)SQLiterDatabase(3)SQLiterOpenHel......