面试常考的自定义排序类题目

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;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值