华为OD 购物

题目

商店里有N件唯一性商品,每件商品有一个价格,第件商品的价格是叫。一个购买方案可以是从N件商品中选择任意件进行购买(至少一件),花费即价格之和。现在你需要求出所有购买方案中花费前K小的方案,输出这些方案的花费。
当两个方案选择的商品集合内至少有一件不同,视为不同方案,因此可能存在两个方案花费相同。
在这里插入图片描述
在这里插入图片描述

自定义链表 排序 & 存放路径 & 路径去重

    static class NodeList {

        Node head;
        int size = 0;

        class Node {
            int val;
            String load;
            Node next;

            public Node() {}

            public Node(int val, String load) {
                this.val = val;
                this.load = load;
            }
        }

        public NodeList(){
            head = new Node();
        }

        public void add(int val, String load) {
            Node p = head.next;
            Node r = new Node(val, load);
            if (p == null) {
                head.next = r;
                size = 1;
                return;
            }
            // 重置路径,不合法不给予添加
            String[] split = load.split("->");
            int[] arr = new int[split.length];
            for (int i = 0; i < split.length; ++i) {
                arr[i] = Integer.parseInt(split[i]);
            }
            Arrays.sort(arr);
            for (int i = 0; i < split.length-1; ++i) {
                if (arr[i] == arr[i+1]) return;
            }

            StringBuffer sb = new StringBuffer();
            for (int i = 0; i < arr.length; ++i) {
                sb.append(arr[i]);
                if(i <arr.length-1) sb.append("->");
            }
            r.load = sb.toString();
            if (!set.contains(r.load)) {
                set.add(r.load);
            } else {
                return;
            }
            size++;
            while (p != null) {
                int tempVal = p.val;
                String tempLoad = p.load;
                if (p.val > val) {
                    p.val = r.val;
                    p.load = r.load;

                    r.val = tempVal;
                    r.load = tempLoad;

                    Node nextNode = p.next;
                    p.next = r;
                    r.next = nextNode;
                    return;
                } else {
                    if (p.next == null || p.next.val > val) {
                        Node t = p.next;
                        p.next = r;
                        r.next = t;
                        return;
                    }
                }
                p = p.next;
            }
        }

        public void remove(int val){
            Node p = head.next;
            Node pre = head;
            while (p != null) {
                if (p.val == val) {
                    pre.next = p.next;
                    size--;
                    p = pre.next;
                } else {
                    pre = pre.next;
                    p = p.next;
                }
            }
        }

        public int size(){
            return size;
        }

        public void printf() {
            Node p = head.next;
            System.out.printf("[ ");
            while (p != null) {
                System.out.printf("%d(%s), ", p.val, p.load);
                p = p.next;
            }
            System.out.printf("]");
        }
    }

主函数

    static HashSet<String> set = new HashSet<>();
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int k = sc.nextInt();
        NodeList nodeList = new NodeList();

        int i = 0, count;
        while (i < n) {
            int val = sc.nextInt();
            nodeList.add(val, i+"");
            i++;
        }
        while (k > 0) {
            NodeList.Node p =  nodeList.head.next;
            NodeList.Node t = p;
            count = 0;
            int min = p.val;
            while (t != null) {
                if (min == t.val) {
                    System.out.println(min+"  "+t.load);
                    count++;
                    k--;
                } else {
                    break;
                }
                t = t.next;
            }
            // 组合
            int g;
            for (NodeList.Node rp = p; rp != null; rp = rp.next) {
                if (nodeList.size >= k + count) break;
                for (NodeList.Node lp = p.next; lp != null; lp = lp.next) {
                    if (nodeList.size >= k + count) break;
                    nodeList.add(rp.val + lp.val, rp.load + "->" +lp.load);
                }
            }
            nodeList.remove(min);
        }
    }
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值