Shopee7.27笔试


题目描述:
给定一个有n个正整数的数组A和一个整数sum,求选择数组A中部分数字和为sum的方案数。
当两种选取方案有一个数字的下标不一样,我们就认为是不同的组成方案。
输入描述:
输入为两行:
第一行为两个正整数n(1 ≤ n ≤ 1000),sum(1 ≤ sum ≤ 1000)
第二行为n个正整数Ai,以空格隔开。
输出描述:
输出所求的方案数
输入:
5 15 5 5 10 2 3
输出:
4

法1搜索(只能通过50%)

import java.util.*;
public class Main {
    int ans=0;
    public static void main(String[] args) {
         Scanner sc=new Scanner(System.in);
         int n=sc.nextInt();
         int k=sc.nextInt();
         int[] a=new int[n];
         for(int i=0;i<n;i++){
             a[i]=sc.nextInt();
         }
         Arrays.sort(a);
         Main m=new Main();
         m.solve(a,0,k,0);       
         System.out.println(m.ans);
    }
    public void solve(int[] a,int cur,int k,int i){
        if(cur==k){
            ans++;
            return;
        }else if(cur>k)
        {
            return;
        }
        for(int j=i;j<a.length;j++){
           solve(a,cur+a[j],k,j+1);
        }       
    }    
}

法二dp

Arrays.sort(a.Collections.reverseOrder())

public class Main{
        public static void main(String[] args) {
              Scanner sc=new Scanner(System.in);
              int n=sc.nextInt();
              int k=sc.nextInt();
              Integer[] a=new Integer[n];
              for(int i=0;i<n;i++){
                  a[i]=sc.nextInt();
              }
              Arrays.sort(a,Collections.reverseOrder());
              int[][] dp=new int[n][k+1];//dp[i][j]前i+1个数字组成j的方案
              for(int i=0;i<n;i++) {
                   dp[i][0]=1;
              }
              for(int i=1;i<=k;i++) {
                  if(a[0]>k)
                      break;
                  if(a[0]==i)
                      dp[0][i]=1;
                  else
                      dp[0][i]=0;
              }
              for(int i=1;i<n;i++) {
                  if(a[i]>k)
                      continue;//直接跳过去
                  for(int j=1;j<=k;j++) {
                      if(j-a[i]>=0)
                          dp[i][j]=dp[i-1][j]+dp[i-1][j-a[i]];//前i-1个数组成组中方案,再加上刚好减去这个数,前i-1个数组成的方案
                      else
                          dp[i][j]=dp[i-1][j];
                  }
              }
              System.out.println(dp[n-1][k]);        
        }
 
}

链表中删除重复的节点,重复的节点可能不是连续的,和之前的有点不太一样

public class Main{
    static class ListNode{
        int val;
        ListNode next=null;
        ListNode(int val){
            this.val=val;
        }
    }
    public static void main(String[] args) {
          Scanner sc=new Scanner(System.in);
          String str=sc.nextLine();
          String[] temp=str.split(" ");
          int[] a=new int[temp.length];
              for(int i=0;i<temp.length;i++) {
                  a[i]=Integer.valueOf(temp[i]);
              }
              Main main=new Main();
              ListNode head=main.CreateListTail(a);
              ListNode res=main.dels(head);
              ListNode i=res.next;
              while(i!=null) {
                  System.out.print(i.val+" ");
                  i=i.next;
              }
    }
    public ListNode CreateListTail(int a[]) {
        ListNode L=new ListNode(0);
        ListNode r=L;
        for(int i=0;i<a.length;i++) {

            ListNode temp=new ListNode(a[i]);
            r.next=temp;
            r=temp;
        }
        return L;
    }
    public static ListNode dels(ListNode head){
        ListNode p=head.next,q;
        ListNode pre=head;
        HashSet<Integer> set=new HashSet<>();
        while(p!=null) {
            if(set.contains(p.val)) {
                p=p.next;
                pre.next=p;
            }
            else {
                set.add(p.val);
                pre=pre.next;
                p=p.next;
            }
        }
        return head;
    }

}

输入ABCABCABC和ABCABC

输出ABC


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM