2024.1.22力扣每日一题——最大交换

news2024/9/29 7:08:26

2024.1.22

      • 题目来源
      • 我的题解
        • 方法一 暴力法
        • 方法一 哈希表+贪心
        • 方法三 贪心

题目来源

力扣每日一题;题序:670

我的题解

方法一 暴力法

直接暴力对数字中的每两个位置进行交换,然后记录交换后生成数字的最大值

时间复杂度:O( log ⁡ 3 m \log^3m log3m)。m是数字num,num的位数是 log ⁡ m \log m logm
空间复杂度:O(KaTeX parse error: Undefined control sequence: \logm at position 1: \̲l̲o̲g̲m̲)

public int maximumSwap(int num) {
    
    String s=""+num;
    int n=s.length();
    int res=num;
    for(int i=0;i<n-1;i++){
        for(int j=i+1;j<n;j++){
            char ch1=s.charAt(i);
            char ch2=s.charAt(j);
            int t=Integer.parseInt(s.substring(0,i)+ch2+s.substring(i+1,j)+ch1+s.substring(j+1,n));
            res=Math.max(res,t);
        }
    }
    return res;


}
方法一 哈希表+贪心
  • 先将数字转为字符串s,然后使用哈希表分别记录每个字符在哪些位置出现,由于后续需要对哈希表的key进行排序(降序),因此选择TreeMap
  • 再依次遍历s,若当前值与哈希表中的第一个key相同,则计数count加1,若count的值与第一个key对应的列表长度一致,删除第一个key对应的Node,并将count置为0
  • 知道哈希表为空或者遍历位置的值与哈希表第一个key不同时退出循环。
    最后,若哈希表为空,则返回原始数字;否则将 遍历的位置和当前哈希表的第一个Node中list的最后一个值对应的数字交换,得到最终交换后的数字

时间复杂度:O(n)
空间复杂度:O(n)

 public int maximumSwap(int num) {
 	String s=""+num;
    TreeMap<Character,List<Integer>> map=new TreeMap<>((a,b)->b-a);
    for(int i=0;i<s.length();i++){
        char ch=s.charAt(i);
        List<Integer> list=map.getOrDefault(ch,new ArrayList<>());
        list.add(i);
        map.put(ch,list);
    }
    int index=0;
    int count=0;
    //这里要注意采用new的方式获取第一个key对应的list,不然会出问题
    List<Integer> list=new ArrayList<>(map.get(map.firstKey()));
    while(!map.isEmpty()&&s.charAt(index)==map.firstKey()){
        list.remove((Integer)index);
        index++;
        count++;
        if(count==map.get(map.firstKey()).size()){
            map.pollFirstEntry();
            count=0;
            //注意删除Node后哈希表为空
            if (!map.isEmpty())
                list=new ArrayList<>(map.get(map.firstKey()));
        }
    }
    if(map.isEmpty()){
        return num;
    }

    count=list.get(list.size()-1);
    return Integer.parseInt(s.substring(0,index)+s.charAt(count)+s.substring(index+1,count)+s.charAt(index)+s.substring(count+1,s.length()));


}
方法三 贪心

参考官方题解。

数字num可以表示为下面:
∑ i = 0 n − 1 d i ∗ 1 0 i \sum_{i=0}^{n-1}{d_i*10^i} i=0n1di10i
假设交换的i和j位上的数字,0<=i<j<n,则最后交换的值为:
在这里插入图片描述
所以若要使交换后的数字最大,交换的两个数字di,dj,0<i<j<n,需要满足以下条件:

  1. dj>di
  2. 在同样大小数字di时,应该使得dj越大才能使得val越大
  3. 在同样大小数字dj时,应使得j的索引值越大才能使得val越大
  4. 在满足1的情况下,应该使得i的索引的越小才能使val越大

因此,具体操作:

  • 将从右向左扫描数字数组,并记录当前已经扫描过的数字的最大值的索引为 maxId 且保证 maxId 越靠近数字的右侧,此时则说明 charArray[maxId]则为当前已经扫描过的最大值。
  • 如果检测到当前数字 charArray[i]<charArray[maxId],此时则说明索引 i 的右侧的数字最大值为 charArray[maxId],此时可以尝试将 charArray[i] 与 charArray[maxId]进行交换即可得到一个比 num更大的值。尝试记录当前可以交换的数对 (i,maxId),根据贪心法则,此时最左边的 iii 构成的可交换的数对进行交换后形成的整数值最大。

时间复杂度:O( log ⁡ m \log m logm)
空间复杂度:O( log ⁡ m \log m logm)

public int maximumSwap(int num) {
    char[] charArray = String.valueOf(num).toCharArray();
    int n = charArray.length;
    int maxIdx = n - 1;
    int idx1 = -1, idx2 = -1;
    for (int i = n - 1; i >= 0; i--) {
        if (charArray[i] > charArray[maxIdx]) {
            maxIdx = i;
        } else if (charArray[i] < charArray[maxIdx]) {
            idx1 = i;
            idx2 = maxIdx;
        }
    }
    if (idx1 >= 0) {
        swap(charArray, idx1, idx2);
        return Integer.parseInt(new String(charArray));
    } else {
        return num;
    }
}

public void swap(char[] charArray, int i, int j) {
    char temp = charArray[i];
    charArray[i] = charArray[j];
    charArray[j] = temp;
}

自己也想到了贪心思想,但是在实际实现的过程中还是火候不到位

有任何问题,欢迎评论区交流,欢迎评论区提供其它解题思路(代码),也可以点个赞支持一下作者哈😄~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1410237.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

下拉回显问题案例大全

下拉回显问题案例大全 一、原生js案例 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>下拉框数据回…

13. 高级IO

13. 高级IO 1. 非阻塞 IO1.1 阻塞 IO 与非阻塞 IO 读文件 2. IO 多路复用2.1 何为 IO 多路复用2.2 select()2.3 poll()2.3.1 struct pollfd2.3.2 poll() 返回值2.3.3 示例 3. 异步 IO3.1 O_ASYNC3.2 设置异步 IO 事件的接收进程3.3 示例 4. 优化异步 IO4.1 使用实时信号替换默认…

android:persistent和android:priority的区别,对进程优先级有什么影响?

前言&#xff1a;写的apk因为系统busy给我kill了&#xff0c;(adj 900): kill all background&#xff0c;在AndroidManifest.xml添加android:persistent"true"后&#xff0c;被甲方要求不能这样做&#xff0c;还是得从adj改&#xff0c;把 priority改成1000 android…

ES6.8.6 为索引映射(Mapping)创建自定义分词器,测试分词匹配效果

文章目录 环境创建索引&#xff1a;配置自定义分词器、字段指定分词器自定义分词器参数说明创建索引&#xff1a;custom_analyzer_comment 使用索引中自定义的分词器进行分词分析自定义分词器my_custom_analyzer分词测试&#xff1a;测试中文停用词、英文字母转小写测试敏感词替…

C++1.0

思维导图 提示输入一个字符串&#xff0c;统计该字符中大写&#xff0c;小写字母个数&#xff0c;数字个数&#xff0c;空格个数以及特殊字符个数&#xff0c;要求使用C风格字符串完成 #include <iostream>using namespace std;int main() {cout << "请输入一…

红包六(CTFshow)

jar的逆向&#xff0c;第一次接触 jd逆向工具反编译jar文件 可以直接丢进去看&#xff0c;也可以用jd反汇编工具看 这里提示flag不在这里分析一下这段代码 1. 引入必要的库: java.util.Base64: 用于处理 Base64 编码和解码。java.util.Scanner: 用于从用户输入中读取文本。…

EasyExcel实现下载模板

实体类&#xff1a; package com.aicut.monitor.domain;import com.alibaba.excel.annotation.ExcelIgnore; import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; import com.alibaba.excel.annotation.ExcelProperty; import com.alibaba.excel.annotation.write.s…

浙大AIF发布年度报告:PaaS是金融机构数智化创新“加速器”

“云原生技术体系日趋成熟&#xff0c;云原生分布式PaaS平台对金融业‘用云价值’发挥三个关键作用——提升多云协同效率、降低数字化门槛和新领域试错成本&#xff0c;正成为中国金融机构数字化转型的加速器。”1月25日&#xff0c;浙江大学国际联合商学院院长、金融科技研究院…

2000-2022年中国对225个国家地区进出口数据

2000-2022年中国对225个国家地区进出口数据 1、时间&#xff1a;2000-2022年 2、来源&#xff1a;UN Comtrade联合国贸易数据 3、指标&#xff1a;、年份、年份、报告国家编码、报告国家ISO编码、报告国家、进出口类别编码、进出口类别&#xff08;import进口/export出口&am…

目标检测数据集 - 人脑肿瘤检测数据集下载「包含VOC、COCO、YOLO三种格式」

数据集介绍&#xff1a;人脑肿瘤检测数据集&#xff0c;真实 CT 场景高质量图片数据&#xff0c;涉及人脑 CT 图片数据集丰富&#xff1b;适用实际项目应用&#xff1a;CT 图片场景下人脑肿瘤检测项目&#xff0c;以及作为通用人脑检测数据集场景数据的补充&#xff1b;标注说明…

HTML 炫酷进度条

下面是代码 <!DOCTYPE html> <html><head><meta charset"UTF-8"><title>Light Loader - CodePen</title><style> html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr…

docker(第二部分)

来自尚硅谷杨哥 少一点胡思乱想&#xff0c;心中无女人&#xff0c;编码自然神&#xff0c;忘掉心上人&#xff0c;抬手灭红尘。人间清醒&#xff0c;赚钱第一。好好学习&#xff0c;天天向上。听懂六六六。 7.Dokcer容器数据卷 1,&#xff09;坑&#xff1a;容器卷记得加入 …

【并发编程】顺序控制交替输出abc

&#x1f4dd;个人主页&#xff1a;五敷有你 &#x1f525;系列专栏&#xff1a;并发编程⛺️稳重求进&#xff0c;晒太阳 必须先2后1打印 用synchronized package aaa;public class Test2 {static Boolean hasExecutorfalse;public static void main(String[] args) …

TS基础知识点快速回顾(上)

基础介绍 什么是 TypeScript&#xff1f; TypeScript&#xff0c;简称 ts&#xff0c;是微软开发的一种静态的编程语言&#xff0c;它是 JavaScript 的超集。 那么它有什么特别之处呢? js 有的 ts 都有&#xff0c;所有js 代码都可以在 ts 里面运行。ts 支持类型支持&#…

华清远见作业第三十三天——C++(第二天)

思维导图&#xff1a; 题目&#xff1a; 自己封装一个矩形类(Rect)&#xff0c;拥有私有属性:宽度(width)、高度(height)&#xff0c; 定义公有成员函数&#xff1a; 初始化函数&#xff1a;void init(int w, int h) 更改宽度的函数&#xff1a;set_w(int w) 更改高度的函数…

优思学院|如何将AI人工智能融入精益六西格玛?

在当前的制造和服务运营中&#xff0c;许多流程都在一定程度上重复进行&#xff0c;这为实验、学习和持续改进其底层流程提供了机会。直到最近&#xff0c;这些流程的改进大多由人类专家执行。然而&#xff0c;随着包括生成型AI在内的人工智能工具的出现&#xff0c;这一切都在…

阅读go语言工具源码系列之gopacket(谷歌出品)----第一集 DLL的go封装

gopacket项目是google出品的golang第三方库&#xff0c;项目源码地址google/gopacket: Provides packet processing capabilities for Go (github.com) gopacket核心是对经典的抓包工具libpcap(linux平台)和npcap(windows平台)的go封装&#xff0c;提供了更方便的go语言操作接…

JavaScript DOM之Cookie详解

cookie有的地方习惯使用复数形式的cookies&#xff0c;指的是网站为了识别用户的身份或者进行一些必要数据的缓存而使用的技术&#xff0c;它的数据是存在用户的终端上&#xff0c;也就是在浏览器上的。 一、什么是cookie 随着互联网的不断发展各种基于互联网的服务系统逐渐多…

3D点云数据的标定,从搭建环境到点云标定方法及过程,只要有一台Windows笔记本,让你学会点云标定

ptscloudpre: 点云标定准备&#xff1a; 说明&#xff1a; 如下介绍适用windows系统的电脑。apple笔记本同理&#xff0c;但是需要安装MAC版本的anaconda。网址&#xff1a;Free Download | Anaconda可下载对应MAC版本的Anaconda的安装包建议下载2022年或2021年的安装包安装。…

nginx限制ip访问

先看一下被禁止的效果 如何配置 禁止访问的话直接在location模块增加类似如下配置 deny all; 完整示例 location / {deny all;root html;index index.html index.htm;} 默认是allow all就是允许所有ip访问,如果只配置指定ip可以访问是无效的,还是所有的ip可以访问 无效示例…