初级编程
数组
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;
}
}