note1

1_1.在一个数组中,求它的连续子数组的最大和,要求时间复杂度为O(n)
[1]第一个最常归的方法,时间复杂度为O(n^3)
记a[i,...,j]为数组a[]上的第i个元素到第j个连续元素构成的数组, i >= 0, j <= n; 
采用枚举有方法
(1)
long getMaxSum(int* ptr, int length) {
assert(ptr != NULL && length > 0);

long ret = ptr[0];
int temp = 0;
for (int i = 1; i < length; i++) {
for (int j = i; j < length; j++) {
for (int k = i; k < j; k++) {
temp += ptr[k];
}

if (temp > ret) {
ret = temp;
temp = 0;
}
}
}

return ret;
}

(2)上述方法可稍稍修改使用时间复杂度为O(n^2)
long getMaxSum(int* ptr, int length) {
assert(ptr != NULL && length > 0);

long ret = ptr[0];
int temp; 
for (int i = 1; i < length; i++) {
temp = 0;
for (int j = i; j < length; j++) {
temp += ptr[j];
if (temp > ret) {
ret = temp;
}
}
}

return ret;
}
[2]采用dp(dynamic programming)动态规划时间复杂度为O(n)
以f(n)表示前n个数中在数组ptr[]中以第n个数结尾的最大连续子序列之和
那么:f(n) = max{f(n - 1) + ptr[n], ptr[n]}   n >= 1;
那么:max{f(0), f(1), ... , f(n)}即为所求 
方法:
long max(long t1, long t2) {
return t1 > t2 ? t1 : t2;
}

long getMaxSum(int* ptr, int length) {
assert(ptr != NULL && length > 0);

long currentMax = ptr[0];
long allMax = currentMax;

for (int i = 1; i < length; i++) {
currentMax = max(currentMax + ptr[i], ptr[i]);
allMax = max(allMax, currentMax);
}

return allMax;
}  

或者
long getMaxSum(int* ptr, int length) {
assert(ptr != NULL && length > 0);

long allMax = ptr[0];

for (int i = 1; i < length; i++) {
allMax = max(allMax, max(allMax + ptr[i], ptr[i]));
}

return allMax;
  }

1_2.在一个环状数组中,求它的连续子数组的最大和,要求时间复杂度为O(n)
我们从结果出发来看,结果最后肯定是从i到j的一个数组,这有两种情况
[1]如果i < j,表明最终连续子数组的最大和,与该数组ptr[]非环状情况一样的结果,
 这时求普通数组ptr[]的最大连续子数组的最大和就可以了
[2]如果i > j,表明最终连续子数组中间跨过了0,这时候从j到i组成的连续子数组和就是最小的
 这时求普通数组ptr[]的总和与最小边续数组和之差即可
  方法:
long max(long t1, long t2) {
return t1 > t2 ? t1 : t2;
}


long min(long t1, long t2) {
return t1 < t2 ? t1 : t2;
} 

long getMaxSum(int* ptr, int length) {
assert(ptr != NULL && length > 0);

long currentMax = ptr[0];
long allMax = currentMax;
long currentMin = ptr[0];
long allMin = currentMin;
long all = ptr[0];

for (int i = 1; i < length; i++) {
currentMax = max(ptr[i], currentMax + ptr[i]);
allMax = max(allMax, currentMax);
currentMin = min(ptr[i], currentMin + ptr[i]);
allMin = min(allMin, currentMin);
all += ptr[i];
} 

return max(allMax, all - allMin);
}
1_3.在一个普通数组中求最大不连续序列和
以f(n)表示前n个数中在数组ptr[]中最大不连续子序列之和
那么:f(n) = max{f(n - 1), f(n - 2) + ptr[n], ptr[n]}   n >= 2;
那么:max{f(0), f(1), ... , f(n)} = f(n)即为所求 
方法依然采用dp
long max(long t1, long t2) {
return t1 > t2 ? t1 : t2;
} 

long getMaxSum(int* ptr, int length) {
assert(ptr != NULL && length > 0);
if (length == 1) {
return ptr[0];
}

long preMax = ptr[0];
long currentMax = ptr[1];
if (length == 2) {
return max(preMax, currentMax);
} 

for (int i = 2; i < length; i++) {
long temp = currentMax;
currentMax = max(currentMax, max(preMax + ptr[i], ptr[i]));
preMax = temp;
} 

return currentMax;
}
1_4.在一个普通数组中求最大连续乘积子串 
以f(n)表示前n个数中在数组ptr[]中以第n个数结尾的最大连续子序列之积
以g(n)表示前n个数中在数组ptr[]中以第n个数结尾的最小边续子序列之积 
那么:f(n) = max{f(n - 1) * ptr[n], g(n - 1) * ptr[n], ptr[n]}   n >= 1;
同时:g(n) = min{f(n - 1} * ptr[n], g(n - 1) * ptr[n], ptr[n])   n >= 1;    
那么:max{f(0), f(1), ... , f(n)}即为所求 
方法:
double max(double t1, double t2) {
return t1 > t2 ? t1 : t2;
}


double min(double t1, double t2) {
return t1 < t2 ? t1 : t2;
} 

double getMaxSum(double* ptr, int length) {
assert(ptr != NULL && length > 0);

double allMax = ptr[0];
double allMin = ptr[0];

for (int i = 1; i < length; i++) {
double allMaxTemp = allMax;
double allMinTemp = allMin;
allMax = max(allMaxTemp * ptr[i], max(allMinTemp * ptr[i], ptr[i]);
allMin = min(allMinTemp * ptr[i], min(allMaxTemp * ptr[i], ptr[i]);
} 

return allMax;
}
1_5.在一个普通数组ptr[]长度为n中,求其中任意(n-1)个元素组成的最大乘积,不能使用乘法,要求
  时间复杂度O(n)
以f(i)表示前i个元数的乘积,则f(i) = ptr[0] * ptr[1] * ... * ptr[i], i >= 0
以g(i)表示后i个元数的乘积,则g(i) = ptr[i] * ptr[i + 1] * ... * ptr[n], i >= 0
以p(i)表示除了第i个元数后剩下(n-1)个元数的乘积,则
那么f(i) = f(i - 1) * ptr[i]; i >= 1,i <= length - 1 
那么g(i) = g(i + 1) * ptr[i]; i >= 1, i <= length - 2
么p(i) = f(i - 1) * g(i + 1); i >= 1, i <= length - 2
以空间换时间
double getMaxSum(double* ptr, int length) {    
double f[length - 1];
double g[length - 1];  
double p[length];

f[0] = ptr[0];
g[length - 1] = ptr[length - 1];

for (int i = 1; i < length; i++) {
f[i] = f[i - 1] * ptr[i];
}

for (int i = length - 2; i > 0; i--) {
g[i] = g[i + 1] * ptr[i];
} 


p[0] = g[1];
p[length - 1] = f[length - 1];

for (int i = 1; i < length - 1; i++) {
p[i] = f[i - 1] * g[i + 1];  
} 

int ret = p[0];
for (int i = 0; i < length; i++) {
if (p[i] > ret) {
ret = p[i];
}
}

return ret;
}

1_6给定一个源字符串和目标串,通过增删改将原字符串转换为新的字符串返回最小操作数
时间复杂度为O(len(source) * len(dest));  
记f(i, j)表示将字符串source[]长度为i,转换为新的字符串dest[]长度为j
所有经历的最小次数.
则f(i, j) = min{f(i - 1, j) + 1, f(i, j - 1) + 1, f(i - 1, j - 1) + source[i] == dest[j] ? 0 : 1 }
f(i- 1, j) + 1表示将源字符串尾部进行删除操作
f(i, j - 1) + 1表示将源字符串尾部进行添加操作
f(i - 1, j - 1) + 1表示将源字符和目标字符串尾部进行替换操作
方法:
int min(int t1, int t2) {
return t1 < t2 ? t1 : t2;  
}

int getMinTrytime(char* source, int lenSource, char* dest, int lenDest) {
int ptr[lenSource][lenDest];
for (int i = 0; i <= lenSource; i++) {
ptr[i][0] = i; 
}

for (int j = 0; j <= lenDest; j++) {
ptr[0][j] = j;
} 

for (int i = 1; i <= lenSource; i++) {
for (int j = 1; j <= lenDest; j++) {
ptr[i][j] = min(
min(ptr[i - 1][j] + 1, ptr[i][ j - 1] + 1)
ptr[i - 1][j - 1] + ptr[i] == ptr[j] ? 0 : 1);
}
}

return ptr[lenSource][lenDest];
}
2_1自定义char* strcpy(char* dest, const char* str)函数
功能:
1.把src开始到含NULL结束的字符串复制到dest开台的空间
char* strcpy(char* dest, const char* str) {
assert(dest != NULL && src != NULL);

char* ret = dest;

while (*deest++ = *src++) {
//do nothing;
} 

return ret;
}  


2_2自定义char* strncpy(char* dest, char* src, int n)函数
1.将src开始的n个这符复制到dest指向的内存中
char* strncpy(char* dest, char* src, int n) {
assert(dest != NULL && str != NULL);

char* ret = dest;
while (n-- > 0) {
*dest++ = *src++;
}

return ret;
}


2_3自定义函数void* memcpy(void* dest, void* src, int n);
1.将src开始的n个字节内容复制到dest中去
void* memcpy(void* dest, void* src, int n) {
assert(dest != NULL && src != NULL);

char* strSrc = (char*)src;
char* strDest = (char*)dest;
void* ret = dest;

while (n-- > 0) {
*strDest++ = *strSrc++;
}

return ret;
}  
2_4自定义函数char* strstr(const char* str1, const char* str2);
时间复杂度为O(len(str1) * len(str2))
1.在字符串str1中找到包含字符串str2的开始位置,并返回这个位置
char* strstr(const char* str1, const char* str2) {
int i, j, k;

for (i = 0; str1[i] != NULL; i++) {
for (j = i, k = 0; str2[k] != NULL && str2[k] == str1[j]; j++, k++) {
//do nothing
}

if (str2[k] == NULL) {
return str1[i];
}
}

return NULL;
}   
3约瑟夫问题
问题描述1.n个人围成一圈,从第1个人从1开始报数每当报到m时,该人从圈中去掉,
接着从下一人从1开始报数
采用环形链表的思想
int lastRemain(int n, int m) {
list<int> members;
for (int i = 0; i < n; i++) {
members.push_back(i);
} 

list<int>::iterator current = members.begin();
list<int>::iterator next;


while (members.length() > 0) {
for (int i = 0; i < m ; i++) {
current++;
if (current == members.end()) {
current = current.begin(); 
} 
}

next = current + 1;
if (next == members.end()) {
next = current.begin();
}
members.erase(current);

current = next;
} 


return current;
}
4_1.快速排序
一次分组时间复杂度为O(n);
int swap(int* t1, int* t2) {
int temp = *t1;
*t1 = *t2;
*t2 = temp;
}
  
int partition(int* data, int start, int end) {
//随机选择基点 
int index = rand() % (end - start + 1) + start;
int small = start;

swap(&data[small], &data[end]);
for (index = start; index < end; index++) {
if (data[index] < data[end]) {
if (small < index) {
swap(&data[small], &data[end]);
}
small++; 
}
}

swap(&data[small], &data[end]);

return small;
}


//快速排序的主体部份
void quickSort(int* data, int start, int end) {
int index = partition(data, start, end);
if (index > start) {
quickSort(data, start, index - 1);
}

if (index < end) {
quickSort(data, index + 1, end);
}
}


4_2最小的K个数,时间复杂度O(n)
void getMinKNumber(int* data, int start, int end, int k) {
int index = partition(data, start, end);
while (index != k) {
if (index > k) {
end = index - 1;
} else if (index < k) {
start = index + 1;
  }

index = getMinKNumber(data, start, end, k);
}
}
5_1求二叉树的深度,采用递归算法
时间复杂度O(lgn)
typedef struct BinaryTreeNode__ {
void* data;
struct BinaryTreeNode__* left;
struct BinaryTreeNode__* right;
} BinaryTreeNode;


int max(int t1, int t2) {
return t1 > t2 ? t1 : t2;
}


int getTreeDepth(BinaryTreeNode* pRoot) {
if (pRoot == NULL) {
return 0;
}

int left = getTreeDepth(pRoot->left);
int right = getTreeDepth(pRoot->right);
return max(left, right) + 1;
}
5_2判断一棵二叉树是不是平衡二叉树 
平衡二叉树要求所有节点的左右子树的高度差不超过1 
思路:后序遍历的话,它会记录左右子树的深度,方向是左 右 中
bool isBalanced(BinaryTreeNode* pRoot, int* depth) {
if (pRoot == NULL) {
*depth = 0;
return true;
}


int depthLeft;
int depthRight;

if (isBalanced(pRoot->left, &depthLeft) &&
   isBalanced(pRoot->right, &depthRight)) {
int diff = depthLeft - depthRight; 
*depth = max(left, right) + 1;

if (diff >= -1 && diff <= 1) {
return true;
} else {
return false;
}
}

return false;
}


bool isBalanced(BinaryTreeNode* pRoot) {
int depth = 0;

return isBalanced(pRoot, &depth);
}


6_1.建造者模式(Builder模式)
public interface Product {


}


public interface Builder {
public Builder buildPartA();
public Builder buildPartB();
public Builder buildPartC();
public Product getProduct();
}


public class ConcreteBuilder implements Builder {
private Product product;

public ConcreteBuilder(Product product) {
this.product = product;
}

public Builder buildPartA() {
...

return this;
}

public Builder buildPartB() {
...

return this;
}

public Builder buildPartC() {
...

return this;
}

public Product getProduct() {
return product;
}
} 


public class Director {
public Builder builder;

public Director(Builder builder) {
this.builder = builder;
}

public Product constructProduct(Builder builder) {
return builder.buildPartA()
  .buildPartB()
  .buildPartC()
      .getProduct();
}
}
6_2抽象工厂模式(abstract factory)
1.抽象工厂
2.具体工厂
3.抽象产品,多个抽象产品,每个抽象产品有多个具体实物
4.具体产品


public interfact AbstractProductA {


}


public interfact AbstractProductB {


}


public class ConcreteProductA1 implements AbstractProductA {


}


public class ConcreteProductA2 implements AbstractProductA {


}


public class ConcreteProductB1 implements AbstractProductB {


}


public class ConcreteProductB2 implements AbstractProductB {


}


public interface AbstractFactory {
public AbstractProductA createProductA();
public AbstractProductA createProductB();
}


public class ConcreteFactory1 implements AbstractFactory {
public AbstractProductA createProductA() {

}

public AbstractProductB createProductB() {

}
}


public class ConcreteFactory2 implements AbstractFactory {
public AbstractProductA createProductA() {

}

public AbstractProductB createProductB() {

}
}
6_3工厂模式
1.一个工厂
2.一个抽象产品
3.多个具体产品
public interface Phone {

}


public class GSMPhone implements Phone {


}


public class CDMAPhone implements Phone {


}


public class PhoneFactory {
public Phone makeGSMPhone() {

}

public Phone makeCDMAPhone() {

}
}


6_4原型模式
1.实现Java的Cloneable接口
public class Prototype implements Cloneable {
@Override
public Object clone() {
Object object = null;

try {
object = super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
}
}   


7_1关于HanderThread
public class HandlerThread extends Thread {
//线程的优先级
private int mPriority;

//线程的Id 
private int mTid = -1;   

//每个Handler必须绑定一个Looper
private Looper mLooper;

public HandlerThread(String name) {
super(name);
mPriority = Process.THREAD_PRIORITY_DEFAULT;
}

public HandlerThread(String name, int priority) {
super(name);
mPriority = priority;
}

//Looper.loop()执行动作之前的一个回调函数
protected void onLooperPrepared() {


}


@Override
public void run() {
mTid = Process.myTid();

//创建本线程的Looper对象 
Looper.prepare();

synchornized (this) {
mLooper = Looper.mLooper();

//通知所有等待该线程的Looper对象的其它子线程,本线程的Looper对象民经就绪 
notifyAll();
}

process.setThreadPriority(mPriority);

//回调用函数
onLooperPrepared();

//开始消息队列的循环
Looper.loop();

mTid = -1;
} 

public Looper getLooper() {
if (!isAlive()) {
return null;
}

//如果已经开始了start()函数,需要等只到looper建好
synchronized (this) {
while(isAlive() && mLooper == null) {
try {
wait();
} catch (InterruptedException e) {

}
}
}

return mLooper;
}

public boolean quit() {
Looper looper = getLooper();
if (looper != null) {
looper.quit();
return true;
}

return false;
}

public int getThreadId() {
return mTid;
}
} 
8_1将一个二进制中的模式001替换为011
001:1
011:3
001 ^ 011:010:2
111:7 
long replace_pattern(long inputInt) {
int andMul = 7;
int compare = 1;
int orMul = 2;
int shift = 0;

for (shift = 0; shift < 31; ) {
if (inputInt & (andMul << shift) == compare) {
inputInt |= orMul << shift;
shift += 3;
} else {
inputInt |= orMul << shift;
shift += 1;
}
}

return inputInt;
} 

9_1一个8*8的格子,A在左下角,B在右下角,求A点到B点的最短路径
void getMinDistance(int row, int col, int* ret) {
if (row < 8) {
getMinDistance(row++, col);
} 

if (col < 8) {
getMinDistance(row, col++);
}

if (row == 8 && col == 8) {
(*ret)++;
} 
}


int getMinDistance() {
int a = 0;
getMinDistance(0, 0, &a);

return a;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值