846. Hand of Straights

本文介绍了一种手牌分组算法,旨在将一组整数形式的手牌重新排列为大小为W的连续数字组。通过使用队列记录每种数字作为顺子开始的数量,算法能够计算下一个数字所需的最少顺子数量,从而排除不符合要求的答案。

Alice has a hand of cards, given as an array of integers.

Now she wants to rearrange the cards into groups so that each group is size W, and consists of Wconsecutive cards.

Return true if and only if she can.

 

Example 1:

Input: hand = [1,2,3,6,2,3,4,7,8], W = 3
Output: true
Explanation: Alice's hand can be rearranged as [1,2,3],[2,3,4],[6,7,8].

Example 2:

Input: hand = [1,2,3,4,5], W = 4
Output: false
Explanation: Alice's hand can't be rearranged into groups of 4

Note:

  1. 1 <= hand.length <= 10000
  2. 0 <= hand[i] <= 10^9
  3. 1 <= W <= hand.length

==============================================================

Ideas: 

For continuous numbers, like  {1,2,3,3,3,4,4,5,5,5,6}  W=3 ,I choose to use a queue to store each number as the number of 'shunzi' beginning, so that I can calculate the minimum number of 'shunzi' next number, and the answer that does not meet the requirements can be ruled out.

==============================================================

Code:

class Solution {
    private LinkedList<Integer> record = new LinkedList<>();
    private int group = 0;
    public boolean isNStraightHand(int[] hand, int W) {
        if(hand.length%W!=0) {
            return false;
        }
        if (W==1) return true;
        Arrays.sort(hand);
        group = W;
        int pre = hand[0];
        int count = 1;
        int minNeed = 0;
        for (int i = 1; i < hand.length; i++) {
            if (pre == hand[i]){
                count++;
            }else {
                if (minNeed>count){
                    return false;
                }else{
                    record.offer(count-minNeed);
                }
                minNeed = count - getNew();
                if (minNeed == 0){
                    record = new LinkedList<>();
                }else if (minNeed<0){
                    return false;
                }else if(pre+1!=hand[i]){
                    return false;
                }
                count = 1;
                pre = hand[i];
            }
        }
        return count == minNeed;
    }
    private int getNew(){
        if (group==record.size()){
            return record.poll();
        }else {
            return 0;
        }
    }
}

    

``` #include <stdio.h> #include <stdlib.h> #include <string.h> // 定义扑克牌与其数值的映射关系结构体 typedef struct { char card[3]; // 扑克牌面(考虑到"10"有两个字符,所以数组大小为3) int value; // 对应的数值 } CardMap; // 扑克牌面到数值的映射表 CardMap card_to_number[] = { {"3", 3}, {"4", 4}, {"5", 5}, {"6", 6}, {"7", 7}, {"8", 8}, {"9", 9}, {"10", 10}, {"J", 11}, {"Q", 12}, {"K", 13}, {"A", 14}, {"2", 16} }; int card_map_size = sizeof(card_to_number) / sizeof(card_to_number[0]); // 用于比较扑克牌的函数 int compare_cards(const void *a, const void *b) { const char *card1 = *(const char **)a; const char *card2 = *(const char **)b; int value1 = 0, value2 = 0; for (int i = 0; i < card_map_size; ++i) { if (strcmp(card_to_number[i].card, card1) == 0) { value1 = card_to_number[i].value; } if (strcmp(card_to_number[i].card, card2) == 0) { value2 = card_to_number[i].value; } } return value1 - value2; } int main() { char input[100]; // 存储输入字符串 char *cards[20]; // 存储分割后的扑克牌字符串指针 int count = 0; // 扑克牌数量 // 读取一行输入 fgets(input, sizeof(input), stdin); input[strcspn(input, "\n")] = 0; // 移除换行符 // 分割输入字符串 char *token = strtok(input, " "); while (token != NULL) { cards[count++] = token; token = strtok(NULL, " "); } // 对扑克牌进行排序 qsort(cards, count, sizeof(char *), compare_cards); // 动态分配二维数组来存储可能的顺子序列 char **straights[count]; int lengths[count]; // 存储每个顺子的长度 for (int i = 0; i < count; ++i) { straights[i] = (char **)malloc(sizeof(char) * count); straights[i][0] = cards[i]; lengths[i] = 1; } int num_straights = count; // 生成顺子序列 for (int i = 0; i < count; ++i) { for (int j = 0; j < num_straights; ++j) { if (compare_cards(&cards[i], &straights[j][lengths[j] - 1]) == 1) { straights[j][lengths[j]++] = cards[i]; break; } } } // 输出长度至少为5的顺子序列 int found = 0; for (int i = 0; i < num_straights; ++i) { if (lengths[i] >= 5) { found = 1; for (int j = 0; j < lengths[i]; ++j) { printf("%s ", straights[i][j]); } printf("\n"); } free(straights[i]); } if (!found) { printf("No\n"); } return 0; }```我希望输入:2 9 J 10 3 4 K A 7 Q A 5 6;输出的结果:3 4 5 6 7 9 10 J Q K A;修改这个代码使得输入输出满足
03-24
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值