初级编程梳理(2)

数组

1.实现一个支持动态扩容的数组

基本思想是当创建的数组满时,将数组复制到另外一个容量为两倍大的数组之中。其他函数同一般数组思想。


public class Array<T> {

    private T[] mArray;
    /**
     * 数组中元素个数
     */
    private int mSize;

    public Array(int length) {

        //noinspection unchecked
        mArray = (T[]) new Object[length];
    }

    public Array() {

        // 默认数组的长度为10
        this(10);
    }


    /**
     * 获取数组长度
     *
     * @return
     */
    public int length() {
        return mArray.length;
    }

    /**
     * 获取数组中元素个数
     *
     * @return
     */
    public int getSize() {
        return mSize;
    }

    /**
     * 判断数组中元素是否为空
     *
     * @return true 是,false 否
     */
    public boolean isEmpty() {
        return mSize == 0;
    }

    /**
     * 在指定位置上添加元素
     *
     * @param index   添加到数组中的位置
     * @param element 需要添加的元素
     */
    public void add(int index, T element) {

        // step 1 判断添加位置的合法性
        // 因为数组的元素添加是连贯性的,所以不可能大于当前数组中元素的个数
        if (index < 0 || index > mSize) {

            throw new IllegalArgumentException("添加失败,添加位置不能负数以及不能大于当前数组元数个数");
        }

        // step 2 当数组无空间后,再添加元素时需要进行扩容
        if (mSize == mArray.length) {

            resize(2 * mArray.length);
        }

        // step 3 添加元素时,先把数组中从最后一个到index位置的元素向后移动
        for (int i = mSize - 1; i >= index; i--) {

            mArray[i + 1] = mArray[i];
        }

        // step 4 最后将index的位置赋值新插入的值
        mArray[index] = element;

        // step 5 数组元素个数加1
        mSize++;
    }

    /**
     * 对原数组进行扩容
     *
     * @param newLength 扩容后的长度
     */
    private void resize(int newLength) {

        //noinspection unchecked
        T[] newArray = (T[]) new Object[newLength];
        //将旧数组元素拷贝到扩容后的数组中
        for (int i = 0; i < mSize; i++) {

            newArray[i] = mArray[i];
        }
        mArray = newArray;
    }

    public void addFirst(T element) {
        add(0, element);
    }

    public void addLast(T element) {
        add(mSize, element);
    }/**
     * 删除指定位置的元素
     *
     * @param index 被删除元素的索引
     * @return 被删除的元素
     */
    public T delete(int index) {

        // step 1 参数合法性判断
        if (index < 0 || index > mSize) {

            throw new IllegalArgumentException("删除失败,删除的元素位置不能负数以及不能大于当前数组元数个数");
        }

        // step 2 根据索引记录被删除的元素并返回
        T ret = mArray[index];

        // step 3 将index之后的元素到最后一个元素向前移动
        for (int i = index + 1; i < mSize; i++) {

            mArray[i - 1] = mArray[i];
        }

        // step 4 数组元素减1
        mSize--;

        // step 5 将未删除元素的原数组的最后一个置为null
        mArray[mSize] = null;

        // step 6 添加元素时,若是对数组进行了扩容,为了不浪费内存空间,
        // 当删除了一定量的元素后,需要对数组进行缩容
        // 缩容缩到什么时候为止了?当mArray.length为1时就没有必要继续缩容了
        if (mSize == mArray.length / 4 && mArray.length / 2 != 0) {

            resize(mArray.length / 2);
        }

        return ret;
    }

    /**
     * 获取指定位置的元素
     *
     * @param index
     * @return
     */
    public T findElement(int index) {

        // 参数合法性判断
        if (index < 0 || index > mSize) {

            throw new IllegalArgumentException("查找失败,查找的元素位置不能为负数以及不能大于当前数组元数个数");
        }
        return mArray[index];

    }

    /**
     * 获取指定元素的位置
     *
     * @param element
     * @return -1 表示不存在
     */
    public int findIndex(T element) {

        for (int i = 0; i < mSize; i++) {

            if (mArray[i].equals(element)) {

                return i;
            }
        }
        return -1;
    }

    /**
     * 查看数组中是否包含指定元素
     *
     * @param element
     * @return
     */
    public boolean contains(T element) {

        for (int i = 0; i < mSize; i++) {

            if (mArray[i].equals(element)) {

                return true;
            }
        }

        return false;
    }
}

2.将两个有序数字合并成一个有序数组

从头遍历两个数组,依次将小的数加到新数组中。

 public int[] SortTwoOrderArray(int[] FistArray, int[] SecondArray){
        int len1 = FistArray.length;
        int len2 = SecondArray.length;
        int[] res = new int[len1 +len2];
        int a1 = 0;
        int a2 = 0;
        int ansnum = 0;
        if(len1 == 0){
            return SecondArray;
        }
        if(len2 == 0){
            return FistArray;
        }
        while (a1 < len1 || a2 < len2){
            if(a1 == len1){
                res[ansnum] = FistArray[a2];
                ansnum++;
                a2++;
            }else if(a2 == len2) {
                res[ansnum] = FistArray[a1];
                ansnum++;
                a1++;
            }
            else if(FistArray[a1] <= SecondArray[a2]){
                res[ansnum] = FistArray[a1];
                ansnum++;
                a1++;
            }else if(FistArray[a1] > SecondArray[a2]){
                res[ansnum] = FistArray[a2];
                ansnum++;
                a2++;
            }
        }
        return res;
    }

3. LeetCode 1. 两数之和(Hash思想)

题目:
给定一个整数数组和一个目标值,找出数组中和为目标值的两个数。
你可以假设每个输入只对应一种答案,且同样的元素不能被重复利用。

示例
给定 nums = [2, 7, 11, 15], target = 9

因为 nums[0] + nums[1] = 2 + 7 = 9
所以返回 [0, 1]

public class TowNumSum {
    public int[] twoSum(int[] nums, int target) {
        int [] ans = new int[2];
        HashMap<Integer,Integer>  map = new HashMap<Integer, Integer>();
        int len = nums.length;
        for (int i = 0; i < len; i++) {
            int temp = target - nums[i];
            if(map.get(temp) == null){
                map.put(nums[i],i);
            }else {
                ans[0] = map.get(temp);
                ans[1] = nums[i];
                break;
            }
        }
        return ans;
    }
}

4. Leetcode202 Happy Number (哈希思想)写一个算法来判断一个数字是否“快乐”。

题目
一个愉快的数字是由下面的过程定义的一个数字:从任何正整数开始,用它的数字的平方代替数字,重复这个过程直到数字等于1(它将停留在哪里),或者在一个不包括1的循环中循环。这个过程以1结尾的数字是快乐数字。
例子:19是一个快乐的数字。

public class  Solution {
    public int getHappyNum(int num){
        int sum  =0;
        while(num != 0){
            sum += (num%10)*(num%10);
            sum = sum/10;
        }
        return sum;
    }

    public boolean isHappy(int num){
        HashSet<Integer> set = new HashSet<Integer>();
        while (!set.contains(num)){
            if(num == 1){
                return true;
            }
            set.add(num);
            num = getHappyNum(num);

        }
        return false;
    }
}

字符串

5. 构造一个只包含a-z字母的单词查找树

public class WordSerchDictionary {
    private class Node{
        public boolean isWord;
        public Node[] next;

        public Node() {
            isWord = false;
            next = new Node[26];//26个英文字母节点
        }
    }
    
    private Node root;

    public WordSerchDictionary() {
        root = new Node();
    }
    
    public void addWord(String word){
        if(word == null){
            return;
        }
        Node temp =root;
        int index;
        for (int i = 0; i < word.length(); i++) {
            index = word.charAt(i) - 'a';
            if(temp.next[index] == null){
                temp.next[index] = new Node();
            }
            temp = temp.next[index];
        }
        temp.isWord = true;
    }
    
    public boolean search(String word){
        return process(root,word);
    }
    
    public boolean process(Node node,String word){
        if(node == null){
            return false;
        }
        
        int index;
        if(word.length() == 1){
            index = word.charAt(0) - 'a';
            return node.next[index].isWord;
        }
        for (int i = 0; i < word.length(); i++) {
            index = word.charAt(i) - 'a';
            if(node.next[index] == null){
                return false;
            }
            node = node.next[index];
        }
        return node.isWord;
        
        
    }
}

6. 暴力匹配字符串

暴力匹配字符串算法是一个一个匹配字符串,其时间复杂度是 O ( m + n ) O(m+n) O(m+n)

public class NaiveStringMatching {

    public boolean stringMatching(String str, String model){
        int len1 = str.length();
        int len2 = model.length();
        if(len1 <len2){
            return false;
        } else {
            for (int i = 0; i < len1 - len2; i++) {
                for (int j = 0; j < len2; j++) {
                    if(str.charAt(i+j) != model.charAt(j)){
                        break;
                    }
                    if(j == len2-1){
                        return true;
                    }
                }
            }
        }
        return false;
    }
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值