【LeetCode算法】初级数组 练习汇总

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;
    }
	
}

你可能感兴趣的:(算法总结)