左神面试算法整理--并归求小和
来源:互联网 发布:贷款抢单软件 编辑:程序博客网 时间:2024/06/08 13:46
算法思想:
此题是求小和问题,求小和问题要用归并排序的思想来解决,只需在并归上稍作修改即可,所以我们要先看一下并归排序。
并归排序的基础知识参见博文:http://blog.csdn.net/left_la/article/details/8656953
本题对归并排序稍作修改,在归并排序时,左边块起始left和右边块起始right进行比较时,若left<right的值,则就加上right及其右边数的个数*left的值。其它和归并过程一样,由小和的定义可以知道,在归并排序过程中,如果左块比右块小,那么遍历到右块数时,都要加一次左块上的那个数。由归并排序可知,这一次排好的块,在下一次和新的右块排序时,此块内数是不在进行比较的,所以不会出现重复加值的情况。
JAVA版
package problems_2017_07_26;
public class Problem_02_SmallSum {
public static int getSmallSum(int[] arr) {
if (arr == null || arr.length == 0) {
return 0;
}
return func(arr, 0, arr.length - 1);
}
public static int func(int[] s, int l, int r) {
if (l == r) {
return 0;
}
int mid = (l + r) / 2;
return func(s, l, mid) + func(s, mid + 1, r) + merge(s, l, mid, r);
}
public static int merge(int[] s, int left, int mid, int right) {
int[] h = new int[right - left + 1];
int hi = 0;
int i = left;
int j = mid + 1;
int smallSum = 0;
while (i <= mid && j <= right) {
if (s[i] <= s[j]) {
smallSum += s[i] * (right - j + 1);
h[hi++] = s[i++];
} else {
h[hi++] = s[j++];
}
}
for (; (j < right + 1) || (i < mid + 1); j++, i++) {
h[hi++] = i > mid ? s[j] : s[i];
}
for (int k = 0; k != h.length; k++) {
s[left++] = h[k];
}
return smallSum;
}
public static void swap(int[] arr, int index1, int index2) {
int tmp = arr[index1];
arr[index1] = arr[index2];
arr[index2] = tmp;
}
public static void main(String[] args) {
int[] arr = { 3, 1, 2, 4, 6, 2, 7, 8, 1 };
System.out.println(getSmallSum(arr));
}
}
C++版
#include<iostream>
#include<stack>
#include<string>
using namespace std;
int merge_sort(int* a,int pre,int mid,int end)
{
int i=pre;
int j=mid+1;
int k=0;
int* h=new int[end-pre+1];
int count=0;
while(i<=mid&&j<=end)
{
if(a[i]<=a[j])
{
count+=a[i]*(end-j+1);
h[k++]=a[i++];
}
else
h[k++]=a[j++];
}
for(;(i<=mid)||(j<=end);i++,j++)
h[k++]=i>mid?a[j]:a[i];
for(int p=0;p<end-pre+1;p++)
a[pre++]=h[p];
delete []h;
return count;
}
int sort(int* a, int pre,int end)
{
if(pre==end)
return 0;
int mid=(pre+end)/2;
return sort(a,pre,mid)+ sort(a,mid+1,end)+merge_sort(a,pre,mid,end);
}
int main()
{
int a[6]={1,3,5,2,4,6};
if(a==NULL)
cout<<"0"<<endl;
int result=sort(a,0,5);
cout<<result<<endl;
system("pause");
return 0;
}
- 左神面试算法整理--并归求小和
- 左神面试算法整理--最大子串和
- 左神面试算法整理---单调栈
- 左神面试算法整理--栈的逆序
- 左神面试算法--哈希表
- 左神面试算法整理--二叉树前、中、后序遍历
- 左神面试算法整理--二叉搜索数最大拓扑结构
- 面试算法题整理
- 算法面试-学习笔记-左旋转字符串
- 常见面试算法题整理
- 面试复习重点 算法 数据结构 【山科大牛陈磊整理】
- 面试复习重点 算法 数据结构 【山科大牛陈磊整理】
- 算法学习和整理
- 备用的文档(整理)左联接和右连接
- 数据结构和算法面试总结
- 数据结构和算法面试总结
- 整理一下算法和数据结构
- 面试整理
- 关于Android的Camera使用总结
- 【二叉树】实现二叉树的前序、中序、后序的非递归遍历
- 百钱百鸡
- 安装并使用node.js
- js框架
- 左神面试算法整理--并归求小和
- vue.js几种不同组件(页面)间传值的方式
- @Temporal——指定查询Date格式
- ros机器人操作系统
- poj 1961 Period(kmp)
- POJ-3021 e-Coins(广搜)
- json工具类
- CPU核数和多线程的关系
- ActiveMQ在数据中的表说明(queue,durable topic)