leetcode 1202. Smallest String With Swaps(交换得到最小的字符串)

别再手动调时间了!用Windows自带的tzutil命令,1分钟搞定时区错误 本文介绍了如何使用Windows自带的tzutil命令快速解决时区错误问题。通过简单的命令行操作,用户可以一键切换时区、查看全球时区代码库,并实现自动化时区同步。相比传统GUI设置,tzutil更可靠且高效,特别适合企业环境批量部署。 阅读详情

You are given a string s, and an array of pairs of indices in the string pairs where pairs[i] = [a, b] indicates 2 indices(0-indexed) of the string.

You can swap the characters at any pair of indices in the given pairs any number of times.

Return the lexicographically smallest string that s can be changed to after using the swaps.

Example 1:

Input: s = “dcab”, pairs = [[0,3],[1,2]]
Output: “bacd”
Explaination:
Swap s[0] and s[3], s = “bcad”
Swap s[1] and s[2], s = “bacd”
Example 2:

Input: s = “dcab”, pairs = [[0,3],[1,2],[0,2]]
Output: “abcd”
Explaination:
Swap s[0] and s[3], s = “bcad”
Swap s[0] and s[2], s = “acbd”
Swap s[1] and s[2], s = “abcd”

给一个字符串s,pairs里面是一对对的数,每一对表示这两个下标对应的字符可以交换位置。
而且可以无限次交换。

问如何利用这些交换使得字符串在字典顺序上最小。

思路:

乍一看像是字符串的问题,实则是graph问题。

把连续的可以交换的点看成一个连通区域,那么这个区域内任意两点都是可以交换的(因为不限制交换次数,总有办法把它们换到想去的地方)。
比如上面example1, 0和3,0和2,1和2可以交换,连在一起就是0,1,2,3可以互换。
既然可以互换,那么就按字典顺序最小的给对应的字符排个序,把排过序的字符插入到排过序的对应下标处,变成了"abcd"。

所以需要解决两个问题:
1)找连通区域。
2)把连通区域内的下标和字符排序,排好序的字符放在排好序的下标处。

方法1:
DFS
找连通区域可以通过建立无向图(邻接链表的形式),用DFS把相连的下标(可以交换的下标)放到一个list,
同时把对应的字符也放入list。

然后对这两个list排序,把排好序的字符放入排好序的下标处。
(因为取出的下标就是这些字符的位置,字符已经按字典顺序排好,要从左往右依次放入排好序的字符,所以这些下标也要排序)。

class Solution {
    List<Integer>[] graph;
    boolean[] visited;
        
    public String smallestStringWithSwaps(String s, List<List<Integer>> pairs) {
        int n = s.length();
        visited = new boolean[n]; 
        graph = new ArrayList[n];
        char[] res = new char[n];
        
        for(int i = 0; i < n; i++) {
            graph[i] = new ArrayList<Integer>();
        }
        
        //构建无向图
        for(List<Integer> pair : pairs) {
            graph[pair.get(0)].add(pair.get(1));
            graph[pair.get(1)].add(pair.get(0));
        }
        
        //遍历每个顶点,找连通区域
        for(int i = 0; i < n; i++) {
            if(visited[i]) continue;
            
            //每个装的都是一个连通区域          
            List<Character> chars = new ArrayList<>();
            List<Integer> ids = new ArrayList<>();
            dfs(s, i, chars, ids);
            
            //把获得到的连通区字符和下标排序,按下标把字符插入到string数组中
            Collections.sort(chars);
            Collections.sort(ids);
            
            for(int j = 0; j < ids.size(); j++) {
                res[ids.get(j)] = chars.get(j);
            }
        }
        
        return new String(res);
    }
    
    void dfs(String s, int idx, List<Character> chars, List<Integer> ids) {
        if(visited[idx]) return;
        chars.add(s.charAt(idx));
        ids.add(idx);
        
        visited[idx] = true;
        
        for(int adj : graph[idx]) {
            dfs(s, adj, chars, ids);
        }
    }
}

方法2:
Union Find
找连通区域还可以用union-find方法,
简单说下,union就类似于聚类,每个可交换的点(有边相连的点)顺藤摸瓜找到它的root,
所以这些点就聚成以root为首的类,把同一类的点直接接到root下面。
下次检索类别的时候就不需要再通过 点1,点2,点3…来找到root,而可以一步找到root。缩短了时间。

find类似于检索,就是找到每个点所属的root。

同一root的点就是一个连通区域。

下面是UnionFind类
rank表示一个root下有多少个点,当然聚类是往点多的类去靠拢。

class UnionFind {
    int[] root;
    int[] rank;
    
    public UnionFind(int n) {
        root = new int[n];
        rank = new int[n];
        
        for(int i = 0; i < n; i++) {
            root[i] = i;
            rank[i] = 1;
        }
    }    
    
    int find(int node) {
        if(node == root[node]) return node;
        return root[node] = find(root[node]);
    }
    
    void union(int n1, int n2) {
        int r1 = find(n1);
        int r2 = find(n2);
        
        //不是同一个root,要union
        if(r1 != r2) {
            if(rank[r1] >= rank[r2]) {
                root[r2] = r1;
                rank[r2] += rank[r1];
            } else {
                root[r1] = r2;
                rank[r1] += rank[r2];
            }
        }
    }
}

然后思路就和上面DFS差不多,也是先找连通区域,存入连通区的下标和字符。
然后排序,注意这里不需要给下标排序,因为下标存入的时候是按顺序访问的。
只需要给字符排序,放入对应的下标中。

这个方法比DFS快很多。

    public String smallestStringWithSwaps(String s, List<List<Integer>> pairs) {
        int n = s.length();
        UnionFind uf = new UnionFind(n);
        HashMap<Integer, List<Integer>> map = new HashMap<>();
        char[] res = new char[n];
        
        for(List<Integer> pair : pairs) {
            uf.union(pair.get(0), pair.get(1));
        }
        
        for(int i = 0; i < n; i++) {
            int root = uf.find(i);
            map.putIfAbsent(root, new ArrayList<Integer>());
            map.get(root).add(i);  //按下标顺序加的,所以连通区的下标已经是排好序的
        }
        
        for(List<Integer> ids : map.values()) {
            char[] chars = new char[ids.size()]; //利用和下标数量一样直接建立数组,比ArrayList快很多
            for(int i = 0; i < ids.size(); i++) {
                chars[i] = s.charAt(ids.get(i));
            }
            
            Arrays.sort(chars);
            for(int i = 0; i < ids.size(); i ++) {
                res[ids.get(i)] = chars[i];
            }
        }
        return new String(res);
    }   
}
超频玩家必看:TestMem5配置文件详解与内存稳定性测试实战(含黄金参数包) 本文详细解析了TestMem5(TM5)在内存超频稳定性测试中的核心价值与实战应用,特别针对DRAM颗粒特性提供黄金参数配置。通过anta777等专业配置的深度剖析,指导超频玩家精准定位内存故障,优化时序参数,实现性能与稳定性的完美平衡。涵盖从初级验证到极限压测的全流程方案,是硬件发烧友提升系统稳定性的必备指南。 阅读详情

相关推荐

群晖NAS下docker安装MySql

本文将一步一步讲解如何在群晖NAS的docker中启用一个MySQL容器 , 算是初学者对问题解决的一个记录.

qq_46375248的博客 5976

ASCII排序 nyoj4

#include void swap(char &a,char &b) { char temp = a; a = b; b = temp; } int main() { int i = 0; scanf("%d",&i); while(i--) { char s[10]; scanf("%s",&s); if(s[0] > s[1])swap(s[0],s[1

脚踏实地,仰望星空 454

从拧螺丝到精密装配:三菱伺服电机扭矩控制在工业自动化中的实战解析

本文深入解析三菱伺服电机扭矩控制在工业自动化中的实战应用,重点介绍MR-J4系列伺服系统的高精度扭矩响应技术。从螺丝紧固到精密装配,详细讲解扭矩控制模式的选择、硬件配置、参数设置及典型故障排查方案,帮助工程师提升生产效率和产品质量。

weixin_29186249的博客 470

【LeetCode】1202. Smallest String With Swaps 交换字符串中的元素(Medium)(JAVA)每日一题

【LeetCode】1202. Smallest String With Swaps 交换字符串中的元素(Medium)(JAVA) 题目地址: https://leetcode.com/problems/smallest-string-with-swaps/ 题目描述: You are given a string s, and an array of pairs of indices in the string pairs where pairs[i] = [a,

qq_16927853的博客 348

ICM42670-P嵌入式开发实战:从寄存器配置到姿态解算全解析

本文全面解析ICM42670-P高性能6轴MEMS运动传感器的嵌入式开发实战,涵盖寄存器配置、数据采集滤波、低功耗优化及姿态解算算法。通过详细代码示例和应用案例,帮助开发者快速掌握从硬件对接到姿态跟踪系统的完整开发流程,适用于可穿戴设备和智能家居等低功耗应用场景。

gold的博客 1064

linux 内核vxlan收发包流程

1.vxlan口收包处理流程 前面几章详细介绍了vxlan接口的使用,而且已经知道vxlan是 MAC IN UDP中的封装,因此,在解封装之前,一切按照原有流程走,在此复习一下内核收发包流程(驱动层的数据处理这次不再解析,直接从__netif_receive_skb_core开始) #物理网卡处理中断,触发softirq i40e_intr └─napi_schedule_irqoff #i40e softirq把包放到per cpu backlog,触发softirq i40e_napi_p

魏言华的博客 3824

LeetCode:1202. Smallest String With Swaps交换字符串中的元素(C语言)

题目描述: 给你一个字符串 s,以及该字符串中的一些「索引对」数组 pairs,其中 pairs[i] = [a, b] 表示字符串中的两个索引(编号从 0 开始)。 你可以 任意多次交换 在 pairs 中任意一对索引处的字符。 返回在经过若干次交换后,s 可以变成的按字典序最小的字符串。 示例 1: 输入:s = “dcab”, pairs = [[0,3],[1,2]] 输出:“bacd” 解释: 交换 s[0] 和 s[3], s = “bcad” 交换 s[1] 和 s[2], s = “bacd

C/C++攻城狮 422

复信号的调制与解调(基带)

Digital modulation methods can be considered as digital-to-analog conversion and the corresponding demodulation or detection as analog-to-digital conversion. 数字调制可以看成是数字到模拟的变换,同样,数字解调也可以看作是模拟向数字的转换。

JonTargaryen的博客 1万+

LeetCode周赛155

1200. Minimum Absolute Difference[1200.MinimumAbsoluteDifference] 最小绝对差,遍历找出最小差,插入vector即可。 class Solution { public: vector<vector<int>> minimumAbsDifference(vector<int>& arr)...

麻花不好吃 274

103.在 Vue 3 中使用 OpenLayers 控制图层来显示/隐藏地图

是一个强大的开源库,可以用于构建各种地理信息系统应用。在 Vue 3 中,我们可以结合。方法,可以直接控制某个图层是否可见,而不需要删除或重新创建图层。在开始之前,确保你已经搭建了 Vue 3 项目,并安装了。本文将详细介绍如何在 Vue 3 组合式 API (,并实现按钮控制地图的显示/隐藏功能。会导致 OSM 瓦片地图无法加载。方法控制地图图层的显示与隐藏。安装完成后,即可开始编写代码。在本教程中,我们介绍了如何在。来实现地图的显示/隐藏功能。来实现交互式地图,并通过。在 WebGIS 开发中,

小彭的博客 1559

【K8S系列】Kubernetes 中 Service 的流量不均匀问题【已解决】

在 Kubernetes 中,Service 是一种抽象,用于定义一组 Pod 的访问策略。当某些 Pod 接收的流量过多,而其他 Pod 的流量较少时,可能会导致负载不均衡。这种情况不仅影响性能,还可能导致某些 Pod 过载,影响应用的可用性。本文将详细分析此问题的原因及其解决方案。

颜淡慕潇 8737

1202. Smallest String With Swaps

You are given a strings, and an array of pairs of indices in the stringpairswherepairs[i] =[a, b]indicates 2 indices(0-indexed) of the string. You canswap the characters at any pair of indices...

Do not mess it up 450

【python】懂车帝字体反爬逐层解密案例(附完整代码)

懂车帝字体反爬解密,完整代码分享

景天科技苑 2万+

字符串this大于字符串that_【LeetCode】1202. 交换字符串中的元素

【LeetCode】1202. Smallest String With Swaps 交换字符串中的元素(Medium)(JAVA)题目描述:You are given a string s, and an array of pairs of indices in the string pairs where pairs[i] = [a, b] indicates 2 indices(0...

weixin_33250328的博客 274

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

[leetcode] 1202. Smallest String With Swaps

Description You are given a string s, and an array of pairs of indices in the string pairs where pairs[i] = [a, b] indicates 2 indices(0-indexed) of the string. You can swap the characters at any pair of indices in the given pairs any number of times. Retu

Learning from the mistakes 276

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

LeetCode 1202. Smallest String With Swaps

You are given a string s, and an array of pairs of indices in the string pairs where pairs[i] = [a, b] indicates 2 indices(0-indexed) of the string. You can swap the characters at any pair of indices in the given pairs any number of times. Return the lexic

Tech in Pieces 403

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

Leetcode-1202. 交换字符串中的元素 Smallest String With Swaps (并查集/DFS) -超详细python

题目 给你一个字符串 s,以及该字符串中的一些「索引对」数组 pairs,其中 pairs[i] = [a, b] 表示字符串中的两个索引(编号从 0 开始)。 你可以 任意多次交换 在 pairs 中任意一对索引处的字符。 返回在经过若干次交换后,s 可以变成的按字典序最小的字符串。 链接:https://leetcode.com/problems/smallest-string-with-swaps/ You are given a string s, and an array of pairs o

JamieLuo的博客 459

【Leetcode】1202. Smallest String With Swaps

排序,接着我们只需要按照字典序回填即可。为了加快速度,我们可以用vector存储每一组下标,然后逆序排序,最后从尾部插入。的排列都能实现,由基于交换的排序的算法可以证明),那么我们可以在每个连通块内部将下标排序,按照。问经过任意次互换之后能得到的最小字典序的字符串是什么。阶图能视为若干连通块的并(因为有这么个定理,如果。允许做任意次将两个元素交换的话,任何。将能交换的下标看成图的点,那么。

数学、算法爱好者的博客 145

LeetCode 1202 Smallest String With Swaps

思路 首先要能想到并且发现,对于任何相连的,或者说在一棵树上pairs,比如[[0, 1], [0, 2], [1, 3], [1, 5], [2, 4], [2, 6]],他们可以通过交换产生任意顺序的排列。证明的方法可以通过表示成树的形式然后分析。简单来说,对于任何两个一棵树上的pair[u, v],都可以通过先将u交换到v,再反过来将v换到原来u的位置实现互换。例如[[0, 1], [0, 3]],1和3互换可以通过swap(0, 1), swap(1, 3), swap(3, 0)来实现。 有了上述

EricJeffrey的博客 189

[leetcode题解] 第1202题Smallest String With Swaps

https://leetcode-cn.com/problems/smallest-string-with-swaps/ 文章目录分析解法并查集排序思路一排序思路二排序思路三 分析 需要把这道题看成图论的题目才好做:将字符串中的索引视为图的节点,一个pair对意味着两个节点之间存在一条无向边。那么答案就可以这样来得到:对无向图中的每个连通分量所代表的字符串分别进行排序,再把字符按照索引填入原位置。 这是因为交换具有传递性,即a与b可交换,b与c可交换,那么a一定可与c交换(交换次数不受限制)。因此在连通分量

chenf1999的博客 300

LeetCode_UnionFind_1202. Smallest String With Swaps 交换字符串中的元素【并查集】【java】【中等】

LeetCode_UnionFind_1202. Smallest String With Swaps 交换字符串中的元素【并查集】【java】【中等】

&再见萤火虫&的博客 618

LeetCode //C - 1202. Smallest String With Swaps

Summary: This problem involves finding the lexicographically smallest string achievable by swapping characters at given indices any number of times. The key idea is to use Union-Find to group all swappable indices into connected components. Characters with

Made in Code 377

并查集系列:1202 Smallest String With Swaps

Smallest String With Swaps You are given a string s, and an array of pairs of indices in the string pairs where pairs[i] = [a, b] indicates 2 indices(0-indexed) of the string. You can swap the characters at any pair of indices in the given pairs any number

WULH 886

【并查集】leetcode1202. Smallest String With Swaps

You are given a string s, and an array of pairs of indices in the string pairs where pairs[i] = [a, b] indicates 2 indices(0-indexed) of the string.You can swap t...

weixin_41348775的博客 162

c语言交换字符串中元素顺序,LeetCode:1202. Smallest String With Swaps交换字符串中的元素(C语言)...

题目描述:给你一个字符串 s,以及该字符串中的一些「索引对」数组 pairs,其中 pairs[i] = [a, b] 表示字符串中的两个索引(编号从 0 开始)。你可以 任意多次交换 在 pairs 中任意一对索引处的字符。返回在经过若干次交换后,s 可以变成的按字典序最小的字符串。示例 1:输入:s = “dcab”, pairs = [[0,3],[1,2]]输出:“bacd”解释:交换 s...

weixin_26741253的博客 458

1202. Smallest String With Swaps(Leetcode每日一题-2021.01.11)

Problem You are given a string s, and an array of pairs of indices in the string pairs where pairs[i] = [a, b] indicates 2 indices(0-indexed) of the string. You can swap the characters at any pair of indices in the given pairs any number of times. Return t

Bryan要加油 544
上一篇: cpp namespace
下一篇: leetcode 1631. Path With Minimum Effort(最小消耗路径)
蓝羽飞鸟
博客等级 码龄8年 1万+粉丝 727原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

蓝羽飞鸟

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值