C/C++每日一练(20230301) 冒泡排序、有效数独、删除有序数组重复项II

这篇文章包含三个编程问题的详细描述:冒泡排序实现,检查9x9数独的有效性,以及在有序数组中删除重复元素(最多保留两次)。每个问题都提供了输入输出示例和部分代码实现,旨在作为每日一练的编程题目供学习者练习。

目录

1. 冒泡排序法排序  🌟

2. 有效的数独  🌟🌟

3. 删除有序数组中的重复项 II  🌟🌟

🌟 每日一练刷题专栏 🌟

Golang每日一练 专栏

Python每日一练 专栏

C/C++每日一练 专栏

Java每日一练 专栏


1. 冒泡排序法排序

输入n(1≤n≤10)个整数,用冒泡排序法对其从小到大排序,共进行n-1趟,要求输出每一趟的排序情况

输入格式:

先输入个数n,再输入n个整数。

输出格式:

第1趟结果

第2趟结果

......

第n-1趟结果

每个数后面有一个空格,每个序列占一行。

输入样例:

5
4 2 3 2 1

输出样例:

2 3 2 1 4
2 2 1 3 4
2 1 2 3 4
1 2 2 3 4

代码:

#include "stdio.h"

int main()
{
    int arr[10];
    int n;
    scanf("%d", &n);
    for (int i = 0; i < n; i++)
        scanf("%d", &arr[i]);
    for (int i = 0; i < n - 1; i++)
    {
        for (int j = 0; j < n - i - 1; j++)
        {
            if (arr[j] > arr[j + 1])
            {
                int t = arr[j];
                arr[j] = arr[j + 1];
                arr[j + 1] = t;
            }
        }
        for (int j = 0; j < n; j++)
            printf("%d ", arr[j]);
        printf("\n");
    }
    
    return 0;
}

输入输出:

5
4 2 3 2 1

2 3 2 1 4
2 2 1 3 4
2 1 2 3 4
1 2 2 3 4

--------------------------------
Process exited after 12.95 seconds with return value 0
请按任意键继续. . .


2. 有效的数独

请你判断一个 9x9 的数独是否有效。只需要 根据以下规则 ,验证已经填入的数字是否有效即可。

  1. 数字 1-9 在每一行只能出现一次。
  2. 数字 1-9 在每一列只能出现一次。
  3. 数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。(请参考示例图)

数独部分空格内已填入了数字,空白格用 '.' 表示。

注意:

  • 一个有效的数独(部分已被填充)不一定是可解的。
  • 只需要根据以上规则,验证已经填入的数字是否有效即可。

示例 1:

输入:board = 
[["5","3",".",".","7",".",".",".","."],
 ["6",".",".","1","9","5",".",".","."],
 [".","9","8",".",".",".",".","6","."],
 ["8",".",".",".","6",".",".",".","3"],
 ["4",".",".","8",".","3",".",".","1"],
 ["7",".",".",".","2",".",".",".","6"],
 [".","6",".",".",".",".","2","8","."],
 [".",".",".","4","1","9",".",".","5"],
 [".",".",".",".","8",".",".","7","9"]]
输出:true

示例 2:

输入:board = 
[["8","3",".",".","7",".",".",".","."],
 ["6",".",".","1","9","5",".",".","."],
 [".","9","8",".",".",".",".","6","."],
 ["8",".",".",".","6",".",".",".","3"],
 ["4",".",".","8",".","3",".",".","1"],
 ["7",".",".",".","2",".",".",".","6"],
 [".","6",".",".",".",".","2","8","."],
 [".",".",".","4","1","9",".",".","5"],
 [".",".",".",".","8",".",".","7","9"]]
输出:false
解释:除了第一行的第一个数字从 5 改为 8 以外,空格内其他数字均与 示例1 相同。 但由于位于左上角的 3x3 宫内有两个 8 存在, 因此这个数独是无效的。

提示:

  • board.length == 9
  • board[i].length == 9
  • board[i][j] 是一位数字或者 '.'

代码:

#include <bits/stdc++.h>
using namespace std;

class Solution
{
public:
	bool isValidSudoku(vector<vector<char>> &board)
	{
		for (int i = 0; i < board.size(); i++)
		{
			vector<bool> mark(10);
			for (int j = 0; j < board.size(); j++)
			{
				if (!valid(board, mark, i, j))
				{
					return false;
				}
			}
		}
		for (int j = 0; j < board.size(); j++)
		{
			vector<bool> mark(10);
			for (int i = 0; i < board.size(); i++)
			{
				if (!valid(board, mark, i, j))
				{
					return false;
				}
			}
		}
		for (int k = 0; k < board.size(); k++)
		{
			int sr = k / 3 * 3;
			int sc = (k % 3) * 3;
			vector<bool> mark(10);
			for (int i = sr; i < sr + 3; i++)
			{
				for (int j = sc; j < sc + 3; j++)
				{
					if (!valid(board, mark, i, j))
					{
						return false;
					}
				}
			}
		}
		return true;
	}
private:
	bool valid(vector<vector<char>> &board, vector<bool> &mark, int i, int j)
	{
		if (board[i][j] != '.')
		{
			int index = board[i][j] - '0';
			if (mark[index])
			{
				return false;
			}
			else
			{
				mark[index] = 1;
			}
		}
		return true;
	}
};

int main()
{
	Solution s;
	vector<vector<char>> board = {
		{'5','3','.','.','7','.','.','.','.'},
		{'6','.','.','1','9','5','.','.','.'},
		{'.','9','8','.','.','.','.','6','.'},
		{'8','.','.','.','6','.','.','.','3'},
		{'4','.','.','8','.','3','.','.','1'},
		{'7','.','.','.','2','.','.','.','6'},
		{'.','6','.','.','.','.','2','8','.'},
		{'.','.','.','4','1','9','.','.','5'},
		{'.','.','.','.','8','.','.','7','9'}};

	cout << s.isValidSudoku(board) << endl;

	board = {
		{'8','3','.','.','7','.','.','.','.'},
		{'6','.','.','1','9','5','.','.','.'},
		{'.','9','8','.','.','.','.','6','.'},
		{'8','.','.','.','6','.','.','.','3'},
		{'4','.','.','8','.','3','.','.','1'},
		{'7','.','.','.','2','.','.','.','6'},
		{'.','6','.','.','.','.','2','8','.'},
		{'.','.','.','4','1','9','.','.','5'},
		{'.','.','.','.','8','.','.','7','9'}};
	
	cout << s.isValidSudoku(board) << endl;
	
	return 0;
} 

输出:

1
0


3. 删除有序数组中的重复项 II

给你一个有序数组 nums ,请你 原地 删除重复出现的元素,使每个元素 最多出现两次 ,返回删除后数组的新长度。

不要使用额外的数组空间,你必须在  原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。

说明:

为什么返回数值是整数,但输出的答案是数组呢?

请注意,输入数组是以「引用」方式传递的,这意味着在函数里修改输入数组对于调用者是可见的。

你可以想象内部操作如下:

// nums 是以“引用”方式传递的。也就是说,不对实参做任何拷贝
int len = removeDuplicates(nums);// 在函数里修改输入数组对于调用者是可见的。
// 根据你的函数返回的长度, 它会打印出数组中 该长度范围内 的所有元素。
for (int i = 0; i < len; i++) {
print(nums[i]);
}

示例 1:

输入:nums = [1,1,1,2,2,3]
输出:5, nums = [1,1,2,2,3]
解释:函数应返回新长度 length = 5, 并且原数组的前五个元素被修改为 1, 1, 2, 2, 3 。 不需要考虑数组中超出新长度后面的元素。

示例 2:

输入:nums = [0,0,1,1,1,1,2,3,3]
输出:7, nums = [0,0,1,1,2,3,3]
解释:函数应返回新长度 length = 7, 并且原数组的前五个元素被修改为 0, 0, 1, 1, 2, 3, 3 。 不需要考虑数组中超出新长度后面的元素。

提示:

  • 1 <= nums.length <= 3 * 10^4
  • -10^4 <= nums[i] <= 10^4
  • nums 已按升序排列
#include <stdio.h>
#include <stdlib.h>

static int removeDuplicates(int *nums, int numsSize)
{
	if (numsSize == 0)
	{
		return 0;
	}
	int i;
	int len = 0;
	int count = 1;
	for (i = 1; i < numsSize; i++)
	{
		if (nums[len] == nums[i])
		{
			if (count < 2)
			{
				count++;
				nums[++len] = nums[i];
			}
		}
		else
		{
			count = 1;
			nums[++len] = nums[i];
		}
	}
	return len + 1;
}

void printResult(int *nums, int count)
{
	printf("%d, nums = [", count);
	for (int i = 0; i < count; i++)
	{
		printf("%d", nums[i]);
		if (i < count - 1)
			printf(",");
	}
	printf("]\n");
}

int main()
{
	int count = 6;
	int nums[count] = {1,1,1,2,2,3};
	count = removeDuplicates(nums, count);
	printResult(nums, count);
	count = 9;
	int nums2[count] = {0,0,1,1,1,1,2,3,3};
	count = removeDuplicates(nums2, count);
	printResult(nums2, count);
	return 0;
}

输出: 

5, nums = [1,1,2,2,3]
7, nums = [0,0,1,1,2,3,3] 


🌟 每日一练刷题专栏 🌟

持续,努力奋斗做强刷题搬运工!

👍 点赞,你的认可是我坚持的动力! 

🌟 收藏,你的青睐是我努力的方向! 

评论,你的意见是我进步的财富!  

 主页:https://hannyang.blog.youkuaiyun.com/

Golang每日一练 专栏

Python每日一练 专栏

C/C++每日一练 专栏

Java每日一练 专栏

评论 4
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Hann Yang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值