1 总结
普通的排序算法一般是按照单个的值的大小进行排序,比如我们对长度为n的一组坐标(x1,y1), (x2,y2), (x3,y3), (x4,y4)… (xn,yn)先按照x轴再按照y轴进行排序的时候,只需要简单的调用排序函数即可,但是如果我们现在有一个全局的坐标(x, y),我们要按照其他点到(x, y)点的距离从小到大排序,那么这样的话就是一种自定义排序,我们可以使用平常使用到的任何一种常规的排序方法实现自顶排序。
2 leetcode 179 最大数
描述:
给定一组非负整数 nums,重新排列每个数的顺序(每个数不可拆分)使之组成一个最大的整数。
注意:输出结果可能非常大,所以你需要返回一个字符串而不是整数。
解答:
class Solution {
// 使用java内部的排序方法实现实现自定义排序, 时间复杂度:O(n*logn)
public String largestNumber(int[] nums) {
int len = nums.length;
String[] str = new String[len];
for (int i = 0; i < len; i++) {
str[i] = nums[i] + "";
}
Arrays.sort(str, (a, b) -> {
return (b + a).compareTo(a + b);
});
StringBuilder sB = new StringBuilder();
for (String s : str) sB.append(s);
if (sB.charAt(0) == '0') {
return "0";
}
return sB.toString();
}
// 手写插入排序方法,实现内部的自定义排序,时间复杂度:O(n^2)
public String largestNumber2(int[] nums) {
int len = nums.length;
StringBuilder sB = new StringBuilder();
int index = -1;
for (int i = 0; i < len; i++) {
int bestnum = 0;
for (int j = i; j < len; j++) {
String str1 = String.valueOf(bestnum);
String str2 = String.valueOf(nums[j]);
if ((str1 + str2).compareTo(str2 + str1) <= 0) {
bestnum = nums[j];
index = j;
}
}
swap(nums, i, index);
sB.append(String.valueOf(bestnum));
}
if (sB.charAt(0) == '0') {
return "0";
}
return sB.toString();
}
public void swap(int[] nums, int i, int j) {
int tmp = nums[i];
nums[i] = nums[j];
nums[j] = tmp;
}
}
3 leetcode 791 自定义排序
描述
给定两个字符串 order 和 s 。order 的所有单词都是 唯一 的,并且以前按照一些自定义的顺序排序。
对 s 的字符进行置换,使其与排序的 order 相匹配。更具体地说,如果在 order 中的字符 x 出现字符 y 之前,那么在排列后的字符串中, x 也应该出现在 y 之前。
返回 满足这个性质的 s 的任意排列
答案
class Solution {
// 时间复杂度:O(m + n)
public String customSortString(String order, String s) {
int map[] = new int[26];
int m = order.length();
int n = s.length();
// 统计s串中各个字符出现的顺序
for (int i = 0; i < n; i++) {
map[s.charAt(i) - 'a']++;
}
// sB用来存放结果
StringBuilder sB = new StringBuilder();
// 因为order中的字符天然有序
// 遍历order串中的每一个字符,根据其在map中的value值来决定添加多少个该字符到sB中。
for (int i = 0; i < m; i++) {
char c = order.charAt(i);
while (map[c - 'a'] >= 1) {
sB.append(c);
map[c - 'a']--;
}
}
// 将最后出现在S串但不在order串中的字符加在末尾
for (int i = 0; i < 26; i++) {
while (map[i] > 0) {
sB.append((char)('a' + i));
map[i]--;
}
}
return sB.toString();
}
// 时间复杂度:O(n^2) n是s串的长度
// 使用java库自带的排序方法实现自定义排序
public String customSortString2(String order, String s) {
Map<String, Integer> map = new HashMap<>();
int m = order.length();
// 使用map先给order中每一个字符排个序
for (int i = 0; i < m; i++) {
map.put(order.charAt(i) + "", i);
}
// 再定义好
List<String> list = new ArrayList<String>(Arrays.asList(s.split("")));
// 对目标串按照其在order中顺序进行排序
Collections.sort(list, (a, b) -> {
return map.getOrDefault(a, m) - map.getOrDefault(b, m);
});
return String.join("", list);
}
}
2022-8-17号华为机试题目:给定一个点(x, y)和长度为n的一组坐标(x1,y1), (x2,y2), (x3,y3), (x4,y4)… (xn,yn),请你从中找出k组距离(x,y)点距离最短的坐标并且让他们按照输入时的顺序排序
思路:新建一个数据结构,里面包含了坐标x,y以及该坐标在输入时的顺序index。同时运用java包提供排序函数,先让他们按照距(x,y)点的距离升序排序,再按照index升序排序
class Node {
int a;
int b;
int index;
public Node(int a, int b, int index) {
this.a = a;
this.b = b;
this.index = index;
}
}
public Node[] returnArr(int x, int y, int arr[][]) {
// 统计各个k-v出现的顺序
int len = arr.length;
Node[] nodeArr = new Node[len];
for (int i = 0; i < len; i++) {
nodeArr[i] = new Node(arr[i][0], arr[i][1], i);
}
Arrays.sort(nodeArr, (Node a1, Node a2) -> {
int distance_a1 = Math.pow((a1.a - x), 2) + Math.pow((a1.b - y), 2);
int distance_a2 = Math.pow((a2.a - x), 2) + Math.pow((a2.b - y), 2);
if (distance_a1 == distance_a2) {
return a1.index - a2.index;
}
return distance_a1 - distance_a2;
});
return nodeArr;
}