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