using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using UnityEngine;
public class Test : MonoBehaviour {
void Start() {
//GetNoRepeatRandom(1,5,3);
//int[] nums = { 1, 2, 3, 4, 5, 6, 7 };
//Rotate(nums,3);
//printList(nums);
//int[] nums1 = { -1, -100, 3, 99 };
//Rotate(nums1, 2);
//printList(nums1);
//SingleNumber(new int[]{4, 1, 2, 1, 2});
//int[] nums1 = { 4, 9, 5 }, nums2 = { 9, 4, 9, 8, 4 };
//printList(Intersect(nums1,nums2));
//int[] nums1 = { 0};
//printList(PlusOne(nums1));
//int a = 10;
//int b = 12;
//a = b + 0 * (b = a);//a=12;b=10
//Debug.Log(b + " " + a);
//int[] nums = { 102, 22, 32, 4, 35, 6, 7 };
//printList(nums);
//Sort(nums,0,nums.Length -1);
int[] nums = { 0, 1, 0, 3, 12 };
MoveZeroes2(nums);
printList(nums);
char[,] cl = new char[9, 9] {
{'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'}};
Debug.Log(IsValidSudoku(cl));
}
/*
有效的数独
判断一个 9x9 的数独是否有效。只需要根据以下规则,验证已经填入的数字是否有效即可。
数字 1-9 在每一行只能出现一次。
数字 1-9 在每一列只能出现一次。
数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。
*/
public bool IsValidSudoku(char[,] board) {
if (board == null)
return false;
int m = 9, n = 9;
bool[,] rowFlag = new bool[9,9];
bool[,] colFlag = new bool[9, 9];
bool[,] cellFlag = new bool[9, 9];
for (int i = 0; i < m;i++){
for (int j = 0; j < n; j++) {
if(board[i,j] >= '1' && board[i,j] <= '9'){
int c = board[i, j] - '1';
if (rowFlag[i, c] || colFlag[c, j] || cellFlag[3 * (i / 3) + j / 3, c])
return false;
rowFlag[i,c] = true;
colFlag[c,j] = true;
cellFlag[3 * (i / 3) + j / 3, c] = true;
}
}
}
return true;
}
public bool IsValidSudoku2(char[,] board) {
//记录行,某位数字是否已经被摆放
var row = new bool[9, 10];
//记录列,某位数字是否已经被摆放
var col = new bool[9, 10];
//记录 某 3x3 宫格内,某位数字是否已经被摆放
// 3 * 3 宫格id indexId = i / 3 * 3 + j / 3
// 0 3 6
// 1 4 7
// 2 5 8
var block = new bool[9, 10];
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
if (board[i, j] != '.') {
//获取数字
var num = board[i, j] - '0';
if (row[i, num]
|| col[j, num]
|| block[i / 3 * 3 + j / 3, num]) {
//数据已经存在,那么直接返回
return false;
} else {
//数据不存在,那么存储相应数据
row[i, num] = true;
col[j, num] = true;
block[i / 3 * 3 + j / 3, num] = true;
}
}
}
}
return true;
}
/*
给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。
你可以假设每种输入只会对应一个答案。但是,你不能重复利用这个数组中同样的元素。
给定 nums = [2, 7, 11, 15], target = 9
因为 nums[0] + nums[1] = 2 + 7 = 9
所以返回 [0, 1]
[3,2,4]
*/
public int[] TwoSum(int[] nums, int target) {
int count = nums.Length;
for (int i = 0; i < count ; i++) {
for (int j = i + 1; j <= count - 1; j++) {
if (nums[i] + nums[j] == target) {
return new int[]{i,j};
}
}
}
return new int[]{};
}
public int[] TwoSum2(int[] nums, int target) {
Dictionary contain = new Dictionary();
for (int i = 0; i < nums.Length; i++) {
if (contain.ContainsKey(target - nums[i])) return new int[] { contain[target - nums[i]], i };
else if (!contain.ContainsKey(nums[i])) contain.Add(nums[i], i);
}
return new int[] { 0, 0 };
}
///
/// 快速排序
///
public void Sort(int[] arr, int low, int high){
if (low >= high)
return;
int index = sortUnit(arr,low,high);
Sort(arr,low,index - 1);
Sort(arr,index + 1,high);
}
public int sortUnit(int[] arr,int low ,int high){
int key = arr[low];
while(low < high){
while(arr[high] >= key && high > low)
--high;
arr[low] = arr[high];
while (arr[low] <= key && high > low)
++low;
arr[high] = arr[low];
}
arr[low] = key;
return high;
}
/*
移动零
给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。
示例:
输入: [0,1,0,3,12]
输出: [1,3,12,0,0]
说明:
必须在原数组上操作,不能拷贝额外的数组。
尽量减少操作次数。
*/
//解法一
public void MoveZeroes(int[] nums) {
int temp, count = 0;
for (int i = 0; i < nums.Length; i++)
if (nums[i] != 0) {
if (count != i) {
temp = nums[count];
nums[count] = nums[i];
nums[i] = temp;
}
count++;
}
}
//解法二
public void MoveZeroes2(int[] nums) {
var zeroIndex = -1;
for (int i = 0; i < nums.Length; i++) {
if (nums[i] != 0) {
zeroIndex++;
if (zeroIndex != i) {
nums[zeroIndex] = nums[i];
}
}
}
if (zeroIndex >= 0) {
zeroIndex++;
while (zeroIndex < nums.Length) {
nums[zeroIndex++] = 0;
}
}
}
//给定一个由整数组成的非空数组所表示的非负整数,在该数的基础上加一。
//最高位数字存放在数组的首位, 数组中每个元素只存储一个数字。
//你可以假设除了整数 0 之外,这个整数不会以零开头。
// 解法一 420ms
public int[] PlusOne1(int[] digits) {
int cont = digits.Length;
for (int i = cont - 1; i >= 0;i--){
if (digits[i] == 9) {
digits[i] = 0;
}
else{
digits[i] += 1;
return digits;
}
}
int[] result = new int[cont + 1];
result[0] = 1;
return result;
}
//解法二 284ms
public int[] PlusOne2(int[] digits) {
int len = digits.Length;
int carry = 1;
len--;
while (len >= 0) {
int sum = digits[len] + carry;
digits[len] = sum % 10;
carry = sum / 10;
len--;
}
if (carry == 0)
return digits;
else {
int[] result = new int[digits.Length + 1];
result[0] = 1;
return result;
}
}
//给定两个数组,编写一个函数来计算它们的交集。
//解法一
public int[] Intersect1(int[] nums1, int[] nums2) {
if (nums1.Length == 0 || nums2.Length == 0)
return new int[]{};
Array.Sort(nums1);
Array.Sort(nums2);
List tempList = new List();
int cont1 = nums1.Length;
int cont2 = nums2.Length;
int i = 0,j = 0;
while(i < cont1 && j < cont2){
if(nums2[j]> nums1[i]){
i++;
}else if(nums2[j]< nums1[i]){
j++;
}
else{
tempList.Add(nums1[i]);
i++;
j++;
}
}
return tempList.ToArray();
}
//解法二
public int[] Intersect2(int[] nums1, int[] nums2) {
List temp = new List();
Dictionary dicOne = new Dictionary();
foreach (int i in nums1) {
if (!dicOne.ContainsKey(i))
dicOne.Add(i, 1);
else
dicOne[i]++;
}
foreach (int t in nums2) {
if (dicOne.ContainsKey(t)) {
if (dicOne[t] <= 0)
dicOne.Remove(t);
else {
temp.Add(t);
dicOne[t]--;
}
}
}
return temp.ToArray();
}
//给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。
//你的算法应该具有线性时间复杂度。 你可以不使用额外空间来实现吗
public int SingleNumber(int[] nums) {
if (nums.Length == 0)
return 0;
int count = nums.Length;
int result = 0 ;
for (int i = 0; i < count; i++) {
result ^= nums[i];
}
return result;
}
//给定一个整数数组,判断是否存在重复元素。
//如果任何值在数组中出现至少两次,函数返回 true。如果数组中每个元素都不相同,则返回 false
public bool ContainsDuplicate(int[] nums) {
if (nums.Length == 0)
return false;
Array.Sort(nums);
int count = nums.Length;
for (int i = 0; i < count - 1; i++) {
if (nums[i] == nums[i + 1])
return true;
}
return false;
}
//给定一个数组,将数组中的元素向右移动 k 个位置,其中 k 是非负数。
//输入: [1,2,3,4,5,6,7]
//和 k = 3
//输出: [5,6,7,1,2,3,4]
//解法一
public void Rotate1(int[] nums, int k) {
if (nums.Length == 0)
return;
int count = nums.Length;
int start = 0;
int i = 0;
int cur = nums[0];
int cnt = 0;
while(cnt++ < count){
i = (i + k) % count;
int t = nums[i];
nums[i] = cur;
if(i == start){
++start;
++i;
if(i < count)
cur = nums[i];
}else{
cur = t;
}
}
}
//解法二
public void Rotate2(int[] nums, int k) {
int len = nums.Length;
k = k % len;
Stack stack = new Stack();
for (int i = 0; i < k; i++) {
stack.Push(nums[len - 1 - i]);
}
for (int i = len - 1 - k; i >= 0; i--) {
nums[i + k] = nums[i];
}
for (int i = 0; i < k; i++) {
nums[i] = stack.Pop();
}
}
private void printList(int[] nums){
string str = "";
for (int j = 0; j < nums.Length; j++){
str = str + " " + nums[j];
}
Debug.Log(" arr =" + str);
}
//从排序数组中删除重复项
public int RemoveDuplicates(int[] nums) {
if (nums.Length == 0)
return 0;
int count = nums.Length;
int i = 0;
for(int j = 1; j < count; j++){
if(nums[i] != nums[j]){
i++;
nums[i] = nums[j];
}
}
return i + 1;
}
public int[] GetNoRepeatRandom(int start, int end, int n) {
if (n <= 0 || start > end) {
return null;
}
int len = end - start + 1;
if (n > len) {
return null;
}
int[] source = new int[len];
for (int i = start; i < start + len; i++) {
source[i - start] = i;
}
int[] result = new int[n];
int index = 0;
for (int i = 0; i < result.Length; i++) {
index = new System.Random().Next() % len--;
result[i] = source[index];
source[index] = source[len];
}
return result;
}
}