文章目录
1 内存对齐
内存对齐是由于CPU读取内存时按照块来读取,块的大小可以为2,4,6,8个字节,具体读取多少个字节和硬件设计有关。因此按照块来读取就会出现所读取数据在一个或者几个块的情况,导致读取操作增加。
这种情况下,四个四个字节读取,刚好一次寻址找到。
第一次:0,1,2,3 第二次:4,5,6,7 第三次:合并 【因此需要更多的时间】
2 不同语言内存管理
c/c++:它的内存管理是通过申请和释放堆的形式完全自主管理的
java:它是使用JVM作内存管理,
python:由私有堆空间管理的,所有的对象和数据结构都在私有堆空间里,只有解释器才能操作。
3 为什么指针在不同操作系统中占用内存不同
在32位操作系统中,指针占4个字节,也就是32位,可存放的数据大小为2^32,也就是4G,因此指针可以寻址4G空间内存。那么针对64位操作系统来说,它的计算机内存都已经超过4位了,因此再使用4字节的指针没有办法寻址到所有的内存空间。
4 二分法运用
4.1 二分查找
class Solution {
public int search(int[] nums, int target) { //查找该元素在数组中的位置
int left = 0;
int right = nums.length - 1;
while (left <= right){
int mid = left + ((right - left) >> 1);
if (nums[mid] < target)
left = mid + 1;
else if (nums[mid] > target)
right = mid - 1;
else
return mid;
}
return -1;
}
}
4.2 搜索插入位置
class Solution {
public int searchInsert(int[] nums, int target) { //元素找不到就返回它应该插入的位置
int left = 0;
int right = nums.length - 1;
int glMid = 0;
while (left <= right ){
int mid = left + ((right - left) >> 1);
if (nums[mid] < target)
left = mid + 1;
else if (nums[mid] > target)
right = mid -1 ;
else
return mid;
glMid = right;
}
return glMid + 1;
}
}
4.3 在排序数组中查找元素的第一个和最后一个位置
class Solution {
public int[] searchRange(int[] nums, int target) {
return new int[]{getLeftBorder(nums, target), getRightBorder(nums, target)};
}
int getLeftBorder(int[] nums, int target){ //查找左边界
int left = 0;
int right = nums.length - 1;
int leMid = -1;
while (left <= right){
int mid = left + ((right - left) >> 1);
if (nums[mid] > target)
right = mid -1;
else if (nums[mid] < target)
left = mid + 1;
else{
right -= 1; //找到了一个相等的,就把right往左移动一个
leMid = mid;
}
}
return leMid;
}
int getRightBorder(int[] nums, int target){ //查找右边界
int left = 0;
int right = nums.length - 1;
int riMid = -1;
while (left <= right){
int mid = left + ((right - left) >> 1);
if (nums[mid] > target)
right = mid -1;
else if (nums[mid] < target)
left = left + 1;
else{
left += 1; 找到了一个相等的,就把left往右移动一个
riMid = mid;
}
}
return riMid;
}
}
4.4 计算非负整数的算数平方根
class Solution {
public int mySqrt(int x) {
int xLeft = 0;
int xRight = x;
int temp = 0;
while (xLeft <= xRight){
int mid = xLeft + ((xRight - xLeft) >> 1);
if ((long)mid*mid > x) //long非常关键,超出int时需要使用
xRight = mid - 1;
else{
temp = mid;
xLeft = mid + 1;
}
}
return temp;
}
}
4.5 计算平方根
class Solution {
public boolean isPerfectSquare(int num) {
int numLeft = 0;
int numRight = num;
while (numLeft <= numRight){
int mid = numLeft + ((numRight - numLeft)/2);
if ((long)mid*mid > num) //long能够防止超时
numRight = mid - 1;
else if((long)mid*mid < num)
numLeft = mid + 1;
else
return true;
}
return false;
}
}
5 双指针在数组中的应用
5.1 删除元素并返回删除后的数组长度
class Solution {
public int removeElement(int[] nums, int val) {
int slowIndex = 0;
for (int fastIndex = 0; fastIndex < nums.length; fastIndex++){
if (nums[fastIndex] != val){ //如果不相等,则慢指针一直跟随快指针
nums[slowIndex] = nums[fastIndex];
slowIndex ++;
}
} //相等的时候快指针往前就好了
return slowIndex;
}
}
5.2 删除数组中重复元素
class Solution {
public int removeDuplicates(int[] nums) {
int lowIndex = 0;
for (int fastIndex = 0; fastIndex < nums.length; fastIndex++){
if (nums[lowIndex] != nums[fastIndex]){
lowIndex ++;
nums[lowIndex] = nums[fastIndex]; //直接用fastIndex的值覆盖lowIndex处的值
}
}
return lowIndex + 1;
}
}
5.3 移动零到最后
class Solution {
public void moveZeroes(int[] nums) {
int lowIndex = 0;
for (int fastIndex = 0; fastIndex < nums.length; fastIndex++){
if (nums[fastIndex] != 0){
nums[lowIndex] = nums[fastIndex];
lowIndex ++;
}
}
for (int i = lowIndex ; i < nums.length; i ++) //在后面补齐0
nums[i] = 0;
}
}
5.4 有序数组的平方
class Solution {
public int[] sortedSquares(int[] nums) {
int[] result = new int[nums.length];
int k = nums.length - 1;
int leftPoint = 0;
int rightPoint = nums.length - 1;
while (leftPoint <= rightPoint){
int leftP = nums[leftPoint] * nums[leftPoint];
int rightP = nums[rightPoint] * nums[rightPoint];
if (leftP <= rightP){
result[k] = rightP;
rightPoint --;
}
else{
result[k] = leftP;
leftPoint ++;
}
k --;
}
return result;
}
}
5.5 滑动窗口找字串
class Solution {
public int minSubArrayLen(int target, int[] nums) {
int left = 0;
int sum = 0;
int result = Integer.MAX_VALUE;
for (int right = 0; right < nums.length; right ++) {
sum += nums[right];
while (sum >= target) {
result = Math.min(result, right - left + 1);
sum -= nums[left];
left ++;
}
}
return result == Integer.MAX_VALUE?0:result; //如果字串长度超过了整数的最大长度,则返回0
}
}
5.6 螺旋矩阵
class Solution {
public int[][] generateMatrix(int n) {
int loop = 0; //圈的个数
int mid = n / 2; //中间那个数,如果是奇数要单独处理
int[][] res = new int[n][n]; //创建新数组存数据
int count = 1; //填充的数字
int i=0,j=0; //i,j分别代表行和列
int start = 0;
while (loop < n/2 ){
loop ++;
//第一排从左到右
for (j = start; j < n - loop; j ++) //n -loop是一个很好的反向思维
res[start][j] = count ++;
//最后一列从上到下
for (i = start; i < n - loop; i ++)
res[i][j] = count ++;
//最后一行从右到左
for (; j >= loop; j --)
res[i][j] = count ++;
//第一列从下到上
for (; i >= loop; i --)
res[i][j] = count ++;
start ++;
}
if (n % 2 == 1)
res[mid][mid] = count;
return res;
}
}