2018.11.1
/*
Move zeros:
input data number:MaxNum;
input data[MaxNum];
*/
#include <stdio.h>
int MaxNum;
int main(void) {
///读取数据保存在data[MaxNum]数组中
printf("please input data number:\n");
scanf("%d\n", &MaxNum);
int data[MaxNum];
///将data[MaxNum]中非零元素挑出按顺序0-向后一次存储,循环完数组,将最后一位非零位后的元素用零填补
if (MaxNum) {
for (int i = 0; i < MaxNum; i++) {
scanf("%d", &data[i]);
}
int k = 0;
for (int j = 0; j < MaxNum; j++) {
if (data[j] != 0) {
data[k] = data[j];
printf("%d\n",data[k]);
k++;
}
}
for(k;k<MaxNum;k++){
data[k] = 0;
printf("%d\n",data[k]);
}
}
return 0;
}
2018.11.2
/*
range-sum-query-immutable
input: Max : arraynum
pre : 起始位置下标
last:终止位置下标
datay:array的值
output:data[pre]+...+data[array]
思路:1getDataInArray()动态分配数组大小,并进行输入;
2rangeSumQuery()依次求前k项和;
3前last项和减去前pre-1项和求出结果输出
*/
#include<stdio.h>
#include<stdlib.h>
int * getDataInArray(int);
int rangeSumQuery(int*, int, int,int);
int Max = 0;
int pre,last ;
int main(void) {
int *r;
///here in code
scanf("%d\n", &Max);
scanf("%d\n", &pre);
scanf("%d\n", &last);
r = getDataInArray(Max);
rangeSumQuery(r, pre, last,Max);
return 0;
}
int *getDataInArray(int Max) {
int *data;
data = malloc(sizeof(int)*Max);
for (int i = 0; i < Max; i++) {
scanf("%d\n", data + i);
} return data;
}
int rangeSumQuery(int *data, int pre, int last,int Max) {
int sum[Max];
for (int k = 0; k <= last; k++) {
if (k == 0) {
sum[0] = data[0];
}
else {
sum[k] = sum[k - 1] + data[k];
}
printf("%d\n", *(sum + k));
}
int a = sum[last];
int b = sum[pre-1];
printf("%d", a - b);
}
input:
9
1
4
1
2
3
4
5
6
7
8
9
output:
1
3
6
10
15
14
2018.11.05
/*
getDataInArray:获取数组--输入: Max--数组长度
findtheduplicatenumber:找到重复元素 输入:Max-数组长度,*data--数组首地址
思路: 1重要亮点重复元素只有一个,数组长n+1,各元素[1,n]
2二分法查找(无序),中值:l+r --起始1+n,
3重复元素在右侧--左更新:l=m+1
重复元素在左侧--右更新:r=m
4终止:l=r
:参考例案: https://mp.weixin.qq.com/s/d-NF2DOxNF_VtvLISajtcA?tdsourcetag=s_pctim_aiomsg
*/
#include<stdio.h>
#include<stdlib.h>
int * getDataInArray(int);
int findtheduplicatenumber(int * ,int );
int Max = 0;
int main(void) {
// code goes here
int *r;
///here in code
scanf("%d\n", &Max);
r = getDataInArray(Max);
findtheduplicatenumber(r,Max);
return 0;
}
int *getDataInArray(int Max) {
int *data;
data = malloc(sizeof(int)*Max);
for (int i = 0; i < Max; i++) {
scanf("%d\n", data + i);
} return data;
}
int findtheduplicatenumber(int * data,int Max){
int l = 1,r=Max ,cnt = 0;
int m = (l+r)>>1;
while(l<r){
for(int i = 0;i<Max; i++){
if(*(data+i)<=m) cnt++;
}
if(cnt<=m) l=m+1;
else{
r=m;
}
}
printf("%d",r) ;
}
LongestIncreasingSubsequence
在上述动态规划算法中,对于数组中的每一个位置,我们都要遍历这个位置前面的所有位置,从而更新以这个位置的数字为结尾的最长公共子序列的长度,先来看一下这个位置之前的递增子序列:
整数数组nums = [10, 9, 2, 5, 3, 7, 101, 18]
当前位置在nums[6] = 101
,
len = 1, tail[0]= 2;
len = 2, tail[1] = 3;
len = 3, tail[2] = 7;
;;
(1)如果再来一个i+1个值是value
if(value>tail[0~i]) 取tail的下标最大的也就是len最大的tail[maxLen] = tailValue;
上述是一个查找问题,采用二分法进行查找。start=0,end=i 查找满足if条件的tail最大下标;
终止条件(start=end)
(1)if(value>tail[maxLen] & maxLen>i ) tail[i++]=value,
if(value>tail[maxLen] & i-1<maxLen<i ) tail[i] = value
tail的下标+1就是len
2018.11.12
/*
1 对数组进行排序;
2 将三数求和转化为二个数求和
3 在两数求和中分三种情况更新start、end下标注意相同元素的处理方式-和start/end更新先后有关
转载自:https://mp.weixin.qq.com/s/0-E_5NjaKrEtP0Ta-Iw7eg?client=tim&ADUIN=26164683&ADSESSION=1541480104&ADTAG=CLIENT.QQ.5585_.0&ADPUBNO=26849
*/
class Solution {
public:
vector<vector<int>> twoSum(vector<int> & nums,int start, int end){
vector<vector<int>> ans;
int sum = 0-nums[start-1];
while(start<end){
vector<int> temp;
temp.push_back(0-sum);
if(nums[start]+nums[end]==sum){
temp.push_back(nums[start]);
temp.push_back(nums[end]);
start++;
while(start<end && nums[start]==nums[start-1]){
start++;
}
end--;
while(start<end && nums[end] ==nums[end+1]){
end--;
}
}
else if(nums[start] + nums[end] > sum){
end--;
while(start<end && nums[end]==nums[end+1]){
end--;
}
}
else if(nums[start]+nums[end] < sum){
start++;
while(start<end && nums[start]==nums[start-1]){
start++;
}
}
if(temp.size()>1){
ans.push_back(temp);
}
}
return ans;
}
vector<vector<int>> threeSum(vector<int>& nums) {
vector<vector<int>> ans;
sort(nums.begin(),nums.end());
int len = nums.size();
for(int i=0 ;i<len-2;i++) { ///3sum数组内部最少还有另外两个数
while(i>0 && nums[i] == nums[i-1]){
i++;
}
vector<vector<int>> temp = twoSum(nums,i+1,len-1);
if(temp.size() != 0 ){ ///调用2Sum有返回值,将返回值加入ans中
ans.insert(ans.end(),temp.begin(),temp.end());///在ans的后面插入temp向量
}
}
return ans;
}
};
2018.11.13
/*
Intersection of Two Arrays
1 将两个数组进行排序;
2 以一个数组为基准进行比较。条件nums1中重复元素将i++,以最后一个为准。
3 注意边界问题否则超限,笨方法在nums1最后压入一个冗余值使数组增长一个单位。(应想出更好的办法解决上限问题)???
https://mp.weixin.qq.com/s/uVyYVpVV_k5uLot8iMxBmg?client=tim&ADUIN=26164683&ADSESSION=1542104347&ADTAG=CLIENT.QQ.5585_.0&ADPUBNO=26849
*/
class Solution {
public:
vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
vector<int> ans;
sort(nums1.begin(),nums1.end());
sort(nums2.begin(),nums2.end());
nums1.push_back(NULL);
int len1 = nums1.size();
int len2 = nums2.size();
int i=0,j=0;
while(i<len1-1 && j<len2){
if(nums1[i]==nums2[j] && nums1[i]!=nums1[i+1]){
ans.push_back(nums1[i]);
i++;
j++;
}
else if(nums1[i] > nums2[j] ){
j++;
}
else if(nums1[i] < nums2[j] || nums1[i]==nums1[i+1]){
i++;
}
}
return ans;
}
};
2018.11.19
/*
338. Counting Bits
转载自https://mp.weixin.qq.com/s/CySQXfCSaJGySpv10W5_Og
1 明白 numb(2^i-2^(i+1))=num(0-2^i)+1 ;
2 第一次循环2^1 :0,1开始;所以size起始值为2;依次循环体现0-2^i前size个数;
3 每当j跟新相当于前j个值已经确定,不断的跟新0-2^i个值
*/
class Solution {
public:
vector<int> countBits(int num) {
vector<int>dp(num + 1, 0);
dp[0] = 0;
if(num == 0) return dp;
dp[1] = 1;
if(num == 1) return dp;
int j = 2;
int size = 2;
while(j <= num) {
for(int i = 0;i < size && j <= num; i ++, j ++) { //size每次变更都是前一次
//因为前面的0~size-1分别加一..
//就是下面的size-2*size-1的个数,依此类推.
dp[j] = dp[i] + 1;
}
size = j;
}
return dp;
}
};