【刷题】数据结构与算法

本博文主要是参照cyc大佬的刷题目录,来记录自己的刷题过程,以备回忆复习专用。

1 数据类型

①数组与矩阵

在一个长度为n的数组里的所有数字都在0到n-1的范围内。 数组中某些数字是重复的,但不知道有几个数字是重复的。也不知道每个数字重复几次。请找出数组中任一一个重复的数字。 例如,如果输入长度为7的数组[2,3,1,0,2,5,3],那么对应的输出是2或者3。存在不合法的输入的话输出-1

    //方法一:使用HashMap,时间复杂度为O(N),空间复杂度为O(N)
    public int duplicate(int[] numbers) {
        HashMap<Integer, Integer> hashMap = new HashMap<>();
        for (int i = 0; i < numbers.length; i++) {
            if (hashMap.containsKey(numbers[i])) {
                hashMap.put(numbers[i], hashMap.get(numbers[i]) + 1);
            } else {
                hashMap.put(numbers[i], 1);
            }
        }
        Set<Integer> integers = hashMap.keySet();
        for (Object intValue : integers) {
            if (hashMap.get(intValue) != 1) {
                return (int) intValue;
            }
        }
        return -1;
    }

    //方法二:使用数据重排,时间复杂度O(N),空间复杂度O(1)。
    // 思想为:重头到尾扫描数组S中的每一个元素,当扫描到第i个元素的时候,
    // 比较第i个元素位置的值m是否等于i,如果相等,则说明该元素已经在排好序的位置,
    // 继续扫描其他元素;如果不相等,先判断m是否等于S[m],相等则说明不同位置上的元素值相等,即元素重复。
    // 直接返回元素;否则交换m和S[m]将他们放置到排好序的位置
    public int duplicate1(int[] numbers) {
        for (int i = 0; i < numbers.length; i++) {
            if (numbers[i] != i) {
                if (numbers[i] == numbers[numbers[i]]) {
                    return numbers[i];
                } else {
                    int temp = numbers[i];
                    numbers[i] = numbers[numbers[i]];
                    numbers[temp] = temp;
                }
            }
        }
        return -1;
    }

注意:数组index如果是变量的话,要注意赋值前index没有改变

在一个二维数组array中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。

//思路:从右上角开始查找,如果找到则返回true,如果比target大则往下走,如果比target小则往左走
public class Solution {
    public boolean Find(int target, int [][] array) {
        if (array == null || array.length == 0 || array[0].length == 0) {
            return false;
        }
        int length = array.length;
        int width = array[0].length;
        int j = width - 1, i = 0;
        while (j >= 0 && i < length) {
            if (array[i][j] == target) {
                return true;
            }
            if (array[i][j] < target) {
                i++;
            } else {
                j--;
            }
        }
        return false;
    }
}

注意:循环遍历二维数组时一定要分清楚i和j应该如何表示行和列

请实现一个函数,将一个字符串s中的每个空格替换成“%20”。
例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy。数据范围:0 \le len(s) \le 1000 \0≤len(s)≤1000 。保证字符串中的字符为大写英文字母、小写英文字母和空格中的一种。

/**
     * 思路:循环遍历字符串,当某个字符为' '时,就添加"%20",使用StringBuilder来拼接最终结果。
     *
     *
     * @param s string字符串
     * @return string字符串
     */
    public String replaceSpace (String s) {
        // write code here
        StringBuilder stringBuild = new StringBuilder();
        for(int i = 0;i < s.length();i++){
            if(s.charAt(i) == ' '){
                stringBuild.append("%20");
            }else{
                stringBuild.append(s.charAt(i));
            }
        }
        return stringBuild.toString();
    }

输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下4 X 4矩阵:
[[1,2,3,4],
[5,6,7,8],
[9,10,11,12],
[13,14,15,16]]
则依次打印出数字
[1,2,3,4,8,12,16,15,14,13,9,5,6,7,11,10]

题目示意图
思路:根据题目所描述,每次顺时针会循环一圈,而这个圈可以用4个点来描述。左上(row1,col1)、右上(row2,col2)、左下(row3,col3)、右下(row4,col4)。其中row1=row2,col1=col3,row3=row4,col2=col4。则以上四个点为左上(row1,col1)、右上(row1,col2)、左下(row3,col1)、右上(row3,coly2),并且只需要row1、row3、col1和col2四个数表示范围。每次顺时针循环时,将输出步骤分为上、右、下和左四个部分,需要注意当row1=row3时上和下的输出结果相等,仅需输出一次即可。col1=col2时左和右的输出结果相等,仅需输出一次即可。

在这里插入图片描述

import java.util.ArrayList;
public class Solution {
    public ArrayList<Integer> printMatrix(int [][] matrix) {
       ArrayList<Integer> resultArray = new ArrayList<>();
        if(matrix == null || matrix.length == 0){
            return resultArray;
        }
        int startRow = 0;
        int startCol = 0;
        int endRow = matrix.length - 1;
        int endCol = matrix[0].length - 1;

        while (startRow <= endRow && startCol <= endCol){
            //上
            for (int i = startCol; i <= endCol ; i++) {
                resultArray.add(matrix[startRow][i]);
            }
            //右
            for (int i = startRow + 1; i <= endRow ; i++) {
                resultArray.add(matrix[i][endCol]);
            }
            //下
            if(startRow != endRow){
                for (int i = endCol - 1; i >=startCol ; i--) {
                    resultArray.add(matrix[endRow][i]);
                }
            }
            //左
            if(startCol != endCol){
                for (int i = endRow - 1; i > startRow ; i--) {
                    resultArray.add(matrix[i][startCol]);
                }
            }
            startRow++;
            endRow--;
            startCol++;
            endCol--;
        }
        return  resultArray;
    }
}

2算法

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值